H2 wiki проекция ADB · dev

← к элементу · к схеме

Онтология h2_shared

Продуктh2_shared
Контурdev
Тип документаОнтология
Координаты чтения{"op": "get_document", "env": "dev", "product": "h2_shared", "doc_type": "Онтология", "latest": true}
Версияh2-shared-ontology-v1.7.19
SHA-256eb20f2d2e538e5eb405e55fd9e261a74d34b6c752cb620ed3594e91aaea13376 сверено
РазмерNone байт

Полный текст

# H2_SHARED_ONTOLOGY v1.7.19

Действующая редакция. История версий хранится в цепочке parent_doc_id реестра ADB.
**Версия:** 1.7.19

**Изменения 1.7.19 (актуализация эпохи, 2026-09-28):** приведено к фактическому состоянию
установленного пакета `h2_shared` **0.56.104** (dev-контур light02, wheel 233, активный deploy 195,
волна WHEEL104; §A2/§A6). Добавлен публичный контракт долговечного хранилища и аутбокса
(`h2_shared.ports.PersistencePort`; §7.2, §7.8); в составе волны — модуль
`h2_shared/ports_durable_mariadb.py`, миграция `0070_add_durable_persistence_tables.sql`,
schema-aware `query_action_logs` (0.56.103) и контракт `--since` ISO-8601 в CLI `h2-logs` (0.56.104).
Состав `MicrotoolResult` (§14, 8 полей) и состав таблиц канона (§A3/§A4, 12 таблиц) подтверждены
без изменения. Структура и версионно-независимые секции сохранены дословно; правки — точечные.
**Изменения 1.7.17 (патч легаси, директива Оператора 25.09.2026):** терминология приведена к
фактической модели — Ring 3 как сервисный слой без LLM; оркестрация платформы — внешние
ИИ-агенты (ПерпКомп, Roo Code) за шлюзом ACO; reasoning-цикл ядра (`Orchestrator`, промпт
C-18 `agent_orchestrator`) помечен LEGACY и допустим только для спец-исполнителей (`test_guide`,
`ai_validation`, `ai_h2_shared_validation`); ссылки на агентскую H2_ONTOLOGY заменены фактами
реестра ADB. Мотивация — регрессия 2026-09-12 (L1 Концепт ACO §0): reasoning-цикл
возвращал константу `"echo"` вместо ответа сервиса.
**Изменения 1.7.18 (errata 1.7.17, 2026-09-25):** зачищена остаточная терминология «агент»
в живом тексте (§2 диаграмма NATS, §5.1 LISTEN_SUBJECT, §5.3 env/NATS-каноны, §C7 заголовок,
таблицы узлов/инвариантов, §11.8.2, инварианты F, §G): «агент(ы)» → «сервис(ы) Ring 3».
Канон-таблица C-01..C-24 сохранена дословно; исторический провенанс §2a-shared и имена кода
(`agents_registry`, `H2_AGENT`, `h2-agent-board`, `H2_<agent>_dyn_<corr8>`) не тронуты.
**applicable_canons:** C-01, C-03, C-04, C-08, C-12, C-13, C-15, C-16, C-17, C-18, C-20, C-22, C-24

## Нормативные ссылки (нейтральный блок, ADR-04)

- **H2_SHARED_ONTOLOGY** (этот документ) — ядро/ОС `h2_shared`.
- **Реестр сервисов** — состав и состояние сервисов Ring 3 (включая спец-исполнителей
  `test_guide`/`ai_h2_shared_validation` и их микротулзы/чекеры) — факты реестра ADB
  (`list_products`, `list_documents`) и карточек сервисов `agent_card.json`.
- **SSOT Index:** `H2_DOCUMENTATION_SSOT_INDEX_v2_7.md` — реестр авторитетности; логическое место канон-каталога и реестра стандартов.
- **Conflict Register:** `H2_CONTRADICTION_REGISTER_v2.md` — реестр противоречий и их статусов.
- **Транзишн-манифест:** `H2_SSOT_TRANSITION_MANIFEST_v1.md` — решения перехода, версии, ACCEPT, откат.
- **Builder Guide (нормативный):** Гайд Пользователя h2_shared — ADB `{"op":"get_document","env":"prod","product":"h2_shared","doc_type":"Гайд Пользователя","latest":true}`.

---

## §0. Ключевая идея (core-подблок из §0/§А.2 источника)

`h2_shared` — это **язык (набор классов и функций) + ОС-обвязка (NATS + MariaDB + MinIO + NSSM)**,
через которые любой сервис Ring 3 говорит с инфраструктурой. Всё, что не является микротулзами и
сервисами бизнес-логики, — принадлежит `h2_shared`. Промпты уровня ядра (§4.5.3) — только для
спец-исполнителей, не для сервисов Ring 3.

Оркестрацию платформы выполняют внешние ИИ-агенты (ПерпКомп, Roo Code) за шлюзом ACO;
ядро оркестрацией не занимается (§0.1, §11.7).

(Упоминание числа и состава сервисов вынесено в реестр ADB; здесь оно намеренно отсутствует.)

---

## §0.1 Принцип платформы (core-подблок, из §0.1 источника)

**h2_shared — это скелет платформы H2.** Оркестрацию платформы выполняют внешние ИИ-агенты
(ПерпКомп, Roo Code) за шлюзом ACO; ядро LLM-оркестрацию не выполняет. Всё остальное — h2_shared:
- runtime (`AgentRuntime`, `run_as_mssn`; `Orchestrator` — LEGACY, только спец-исполнители, §11.7);
- транспорт (`nats_client`, subjects convention);
- логирование (`h2_logging`, C-16 TOTAL-LOG, C-18 `PromptLoader`);
- контракты (`contracts/*`, A2A envelope);
- инфраструктура (`kv_board`, `kv_schemas`, `mysql_pool`, `object_store_config`);
- self-validation (`self_validation/*`).

**Следствия (обязательные к исполнению), в абстрактной форме:**
1. В коде `h2_shared/*.py` запрещены импорты из любого пакета сервисного слоя (Ring 3), хардкод
   путей на диске к сервисам, хардкод строк-имён сервисов как default/ключей словаря, хардкод
   subject'ов вида
   `"<agent>.request"` (использовать `h2_shared.contracts.subjects`).
2. Единственный допустимый источник конфигурации сервиса внутри `h2_shared` — SQL `agents_registry`
   (агент+версия+card_json; имя таблицы — канон кода) и `prompts_registry` (промпты — LEGACY,
   только спец-исполнители).
3. Self-validation checks — единственные легитимные места, где имена сервисов упоминаются в
   `h2_shared` (специальные exception'ы, перечисляющие FORBIDDEN-имена именно чтобы запретить).
4. Docstring'и/комментарии — допускают имена сервисов только как examples, без hardcode в исполняемом коде.

> Конкретный список forbidden-имён self-validation — факт реестра ADB (карточки сервисов).

**Cross-ref:** §7 R-*-CENTRAL правила; §7.1 «h2_shared = kernel».

---

## §1. Существование 4 стандартов (REFERENCE)

В системе существуют **4 универсальных стандарта**, регулирующих контракт ролей
ии-кодер ↔ ии-архитектор ↔ app_agent и структуру workspace сервиса:
`STANDARD_MAS`, `STANDARD_AFAD`, `STANDARD_DOC_TEMPLATES`, `STANDARD_WORKSPACE_HYGIENE`.

`h2_shared` только регистрирует факт их существования. **Каталог/реестр стандартов** (версии,
предметы) — не размещается здесь как норма; его физическое место — явно OPEN (CONF-ONT-01), логически —
SSOT Index. Внутреннее устройство h2_shared (kernel API, импорты, classes) — предмет §7 этой
онтологии, а не стандартов (это мета-разграничение зафиксировано в §1.2 источника, здесь дано
как REFERENCE).

---

## §4. NATS и JetStream — общая схема

### 4.1 Схема

```
                        ┌──────────────────────────────────────┐
                        │  NATS heavy01 (nats://192.168.99.11) │
                        │       :4222 — единая infra точка     │
                        │   Все сервисы подключаются СЮДА       │
                        │   (NATS_URL/SERVERS=...99.11:4222)   │
                        └──────────────────────────────────────┘
         ┌──────────────────────────────┼──────────────────────────────┐
         ▼                              ▼                              ▼
    Streams (12)                  KV Buckets (7+)               Object Store (2)

   Laptop NATS (nats://127.0.0.1:4223): опциональный релей, JetStream НЕ доступен.
   Production-путь: сервисы → heavy01:4222 напрямую (§5.3 п.7, §K).
```

### 4.2 Streams (12 на heavy01)
`h2-events` (`h2.>` catch-all); `ai_validation` (`ai.validation.>`, АНОМАЛИЯ вне `h2.*`);
`KV_H2_CONFIG`; `KV_H2_SECRETS`; `KV_h2-agent-board`; `KV_h2-daily-health`; `KV_h2-dedup`;
`KV_h2-wheels`; `KV_kv_board`; `OBJ_h2-artifacts`; `OBJ_h2-prompts`;
`h2-audit` (`h2.audit.log.write` — не используется: запись в `h2_logs` идёт прямым INSERT
через `H2Audit.insert_h2_log()`, NATS-транспорт не применяется — §11.8.3a).

### 4.3 Subjects (закрытый список из кода, ~13 уникальных)
`h2.validation.request`, `h2.validation.>`, `h2.ai_validation.>`,
`h2.health.heartbeat.{agent_name}` (PUBLISH runtime, без `@{host}`),
`h2.system.ping`, `h2.system.health.snapshot`, `h2.system.test`,
`h2.events.dead_pid_detected`, `h2.events.process_restarted`, `h2.events.roo_task_draft`,
`h2.events.agent_silent`, `h2.events.agent_recovered`.
Закрытый список = эти 13 + аналоги для других сервисов по паттерну `h2.<agent_short>.request`.

**Единый SSOT-резолвер subject.**
Request- и response-subject резолвятся через единый runtime-источник —
`h2_shared/constants.py`: `resolve_request_subject(agent)` и
`resolve_response_subject(agent)`. Этот резолвер используют publisher
(`runtime/transport.py::_resolve_subject`) и listener-пути
(`runtime/agent_runtime.py::run_as_listener`, `run_dry_run_full`,
`runtime/app_router.py::AppRouter.request_subject`).

`AppRouter.REQUEST_SUBJECT_TPL` сохранён только как DEPRECATED compatibility-атрибут
и не участвует в runtime-резолюции.

Правила request-subject:
- `ai_validation` (AVAL) → `h2.validation.request` (карточка сервиса, реестр ADB);
- `ai_h2_health` → `ai.health.request` (карточка сервиса, реестр ADB);
- остальные сервисы → `h2.{agent}.request`.

Классовый `LISTEN_SUBJECT` сервиса, включая `ValidationAgent.LISTEN_SUBJECT`,
не является авторитетным источником для runtime-подписки: listener использует
результат `resolve_request_subject(agent_name)`. Поле `LISTEN_SUBJECT` в карточке
сервиса сохраняется как декларативное/диагностическое и обязано совпадать с
результатом резолвера. Расхождение должно обнаруживаться валидатором, а не
изменять runtime-subject.

### 4.4 KV Buckets
`h2-agent-board` (live registry, C-08); `H2_CONFIG`; `H2_SECRETS` (Tier 2, §S);
`h2-daily-health`; `h2-dedup`; `h2-wheels`; `kv_board`. Каноном является только
`h2-agent-board` (lowercase-kebab, C-08, R-16-CENTRAL); uppercase-форма не применяется.

### 4.5 Object Store (NATS) vs MinIO
NATS Object Store (`OBJ_h2-artifacts`, `OBJ_h2-prompts`) — маленькие артефакты, low-latency.
MinIO (heavy01:9000) — крупные бинари, wheels, дампы. Это **разные хранилища**.

---

## §4.5 KV-Board и промпт оркестратора (механизм ядра)

### 4.5.1 kv_board
`h2-agent-board` (C-08) — живая доска состояния сервисов в NATS KV. Каждый сервис при старте
публикует туда своё состояние.

### 4.5.2 Схема записи
Ключ: `<agent_name>`. Значение: JSON c `agent_name`, `version`, `status`
(`running|degraded|down`), `started_at`, `last_heartbeat`, `host`, `pid`, `listen_subject`,
`live_scenario_path`, `agent_kv_card_sha256`, `h2_shared_version`.

### 4.5.3 Промпт reasoning-цикла ядра (canon C-18) — LEGACY, только спец-исполнители
- **Имя:** `agent_orchestrator` (SQL `prompts_registry.name`); версия в `prompts_registry.version`.
- **Статус (1.7.17):** LEGACY. Допустим только для спец-исполнителей (`test_guide`, `ai_validation`,
  `ai_h2_shared_validation`) при явном решении; для сервисов Ring 3 запрещён — регрессия
  2026-09-12: reasoning-цикл игнорировал `answer` из start.py и возвращал константу `"echo"`
  (L1 Концепт ACO §0). Реальная оркестрация платформы — внешние оркестраторы
  (ПерпКомп, Roo Code) за шлюзом ACO.
- **Плейсхолдеры (5):** `{{agent}}`, `{{agent_version}}`, `{{phase_id}}`, `{{tools_catalog_rendered}}`
  (pretty-print `agents_registry.card_json.microtools[]`; h2_shared сам рендерит), `{{scratchpad_rendered}}`.
- **Загрузка:** только через `PromptLoader.load(name="agent_orchestrator")` с записью в `h2_logs`
  (component=`prompts_registry`, action=`PROMPT_LOAD`, canon C-18).
- **Разделение с `prompt_semantic_reasoner`:** последний — промпт **ии-арха**, не вызывается в
  runtime; `agent_orchestrator` — runtime-промпт reasoning-цикла ядра (LEGACY, спец-исполнители).

Связь «спец-исполнитель → какие сервисы живы → drift в BL» — факт реестра ADB (REFERENCE).

---

## §5. Топология сервисов и NSSM-канон

### 5.1 Топология (КАНОН, закрытый список)
| Хост | IP | Роль | Что крутится |
|---|---|---|---|
| **heavy01** | 192.168.99.11 | ТОЛЬКО ИНФРА | NATS (4222), MinIO (9000), log_sink |
| **laptop** | 127.0.0.1 | ТОЛЬКО RING 3 + MariaDB | NSSM-сервисы Ring 3 + MariaDB (localhost:3306) + локальный NATS-реле (4223, без JetStream) |
| **edge** | 161.104.53.48 (Selectel VPS) | ПУБЛИЧНЫЙ КОНТУР (Ring E) | Caddy TLS + edge-adapter + NATS leaf |

Агенты **никогда** не запускаются на heavy01. Инфра (кроме MariaDB) **никогда** не на laptop.

### 5.2 NSSM-сервисы (закрытый список)
`nats-server` (heavy01, RUNNING), `mariadb` (laptop:3306, RUNNING), `minio` (heavy01, RUNNING),
`log_sink` (heavy01, RUNNING). Сервисы Ring 3 — факт реестра ADB (`list_products`, карточки сервисов).

### 5.3 NSSM-канон (правила ядра работы со службами)
1. Имя сервиса = `h2-<agent_name>` с дефисами.
2. stdout/stderr → `D:\<agent>\<agent>_data\logs\nssm_stdout.log`/`nssm_stderr.log`.
3. Restart policy: AppRestartDelay 5000 ms, AppExit Default Restart.
4. Аккаунт LocalSystem по умолчанию.
5. Bootstrap `D:\<agent>\bootstrap.ps1` — единственный источник правды регистрации сервиса.
6. Оператор не регистрирует сервисы руками, кроме UAC-необходимости.
7. **NATS_URL канон:** `NATS_URL`/`NATS_SERVERS` каждого сервиса обязан указывать на
   `nats://192.168.99.11:4222` (heavy01). `127.0.0.1:4223` для production запрещён (JetStream
   недоступен через локальный релей). См. §K.

8. **Закрытый список env-переменных Ring 3 листенера.**
   Через AppEnvironmentExtra сервису передаются **только** host-level и identity-переменные.
   **D-6:** этот whitelist применяется **и к дочернему MSSN**, создаваемому `MssnSpawner.spawn()`
   (GUIDE §9.3). Канонический 5-var набор: `H2_AGENT`, `PYTHONPATH`, `AGENT_ROOT`,
   `H2_EVIDENCE_DIR`, `H2_SECRETS_FILE`. `MssnSpawner` наследует эти переменные из `os.environ`
   родительского процесса листенера. Если `H2_SECRETS_FILE` отсутствует — spawn отвергается с
   `BLOCKED`. Основание: ESCALATION_D6_MSSN_SECRETS_INHERITANCE_v1.
   - `NATS_SERVERS` — canonical URL (см. §K.2)
   - `H2_DOMAIN` — default `h2`
   - `H2_AGENT` — имя сервиса (может быть также в CLI --agent)
   - `H2_LOG_DIR` — опционально, default `%LOCALAPPDATA%\h2\logs\<agent>`

   **Запрещено** в AppEnvironmentExtra: `MARIADB_AUDIT_URL`, `MARIADB_ROOT_PASSWORD`,
   `DEEPSEEK_API_KEY`, `TG_BOT_TOKEN`, `MINIO_ACCESS_KEY`, `MINIO_SECRET_KEY`,
   `NATS_AUTH_TOKEN` — эти ключи резолвятся h2_shared через внутренний механизм
   (см. §S). Наличие любого из этих ключей в AppEnvironmentExtra = **REJECT_FRAUD** на
   Acceptance.

9. **NSSM AppEnvironmentExtra синтаксис под LocalSystem.**
   Каноническая форма — **одиночный вызов** `nssm set <SVC> AppEnvironmentExtra ":KEY1=VAL1 KEY2=VAL2 ..."`:
   - **ведущее `:`** — replace-mode, обязательно под LocalSystem;
   - **пробельные разделители** между парами `KEY=VAL`;
   - **без переносов строк**, без `+KEY=VAL` (per-var append не работает под LocalSystem
     в NSSM 2.24-101 — evidence PMA_v4_3 STOP-7).

   Проверка после `nssm set`: `nssm get <SVC> AppEnvironmentExtra` должно вернуть ту же строку
   с ведущим `:`.

10. **AppExit policy Ring 3 листенера.**
    Каноническая политика: `AppExit Default Exit` (fail-fast; NSSM не рестартит сервис при
    аварийном exit). Это даёт Acceptance-скрипту возможность увидеть один stderr-лог, а не
    циклический перезапуск. `AppExit Default Restart` разрешён только для production stable
    сервисов после ACCEPT.

---

## §C7. LIVE-RUN canons для сервисов Ring 3

Обязательные операционные каноны для любого сервиса Ring 3, выполняющего LIVE-RUN
(установка, preflight, NSSM, проверка listener, NATS request-reply, teardown). Каждый
PMA-скрипт сервиса Ring 3 **MUST** следовать этим канонам.

### C7.1 Shell canon

- PMA-скрипты выполняются **ТОЛЬКО** в PowerShell 5.1+.
- `cmd.exe` запрещён для preflight, NSSM install/start, evidence-записи.
- Проверка в §P-0 preflight: `$PSVersionTable.PSVersion.Major -ge 5`.

### C7.2 SQL evidence-query canon (Ring 3)

- Ring 3 **НЕ** имеет прямого доступа к MariaDB. `mysql.exe`/mariadb-client в Ring 3 запрещены.
- Ring 3 **НЕ** импортирует `h2_shared.security`, `h2_shared.audit.internal`, `mariadb`.
- Для evidence-запросов в PMA-скриптах используется h2_shared CLI-утилита:
  ```
  python -m h2_shared.evidence.query "SELECT ..." --format json
  ```
  Утилита сама читает DSN из `HOST_REGISTRY.yaml` внутри пакета, применяет
  read-only guard, возвращает JSON в stdout, диагностику в stderr.
- Если утилита отсутствует в текущей версии h2_shared — эскалация арх, а не
  прямой mariadb-driver обход.

### C7.3 Admin elevation canon

- `nssm install/start/remove` требует Administrator.
- Каждый PMA-скрипт начинается self-elevation check:

```powershell
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
    exit
}
```

- Elevation происходит **ДО** P-0, чтобы preflight запускался уже в admin-контексте.

### C7.4 NATS reachability canon (Ring 3, zero-knowledge)

- Ring 3 **НЕ** знает адрес и порт NATS. `Test-NetConnection` с явным адресом запрещён.
- Проверка NATS в preflight — через h2_shared CLI-утилиту:
  ```
  python -m h2_shared.probe.nats --timeout 3
  ```
  Утилита сама читает URL из `HOST_REGISTRY.yaml`, пытается TCP + ping,
  возвращает exit-code 0/1 + JSON в stdout (URL маскирован).
- Если утилита отсутствует — эскалация арх.

### C7.5 NSSM AppExit canon (правильный синтаксис)

- `nssm set <svc> AppExit Default Restart` — **три отдельных аргумента**.
- Корректная запись в PS:

```powershell
& nssm.exe set $Svc AppExit Default Restart
```

- **НЕ** передавать как одну строку `"AppExit Default Restart"`.
- Проверка в `nssm_config.txt`: строка `AppExit = Default Restart` должна присутствовать.

### C7.6 Heartbeat query timing canon

- `service_health` таблица запрашивается **ДО** teardown (после §5, до §6).
- Между стартом сервиса и heartbeat query — минимум 15 сек (heartbeat loop 10s + запас).
- После teardown heartbeat-строк не будет — это ожидаемо, не считать за успех/ошибку.

---

## §6. SQL-таблицы (канон 12 в h2_audit)

Канон — **ровно 12 таблиц**, сверено с живой `information_schema` базы `h2_audit`
(dev-контур light02, read-only через `python -m h2_shared.evidence.query`, C7.2) и с
миграциями/схемой/seeds установленного пакета h2_shared 0.56.104.

| # | Таблица | Роль | Writer (код-владелец) | Reader (код-владелец) |
|---|---|---|---|---|
| 1 | `h2_logs` | журнал TOTAL-LOG (C-16/C-20) | `audit.h2_audit.H2Audit.insert_h2_log` | `logs.query.LogQuery.tail/by_correlation_id`; `cli.h2_logs` |
| 2 | `h2_mssn_runs` | MSSN-прогоны | `audit.h2_audit.H2Audit.create_mssn/finalize_mssn/update_mssn`; `runtime.mssn_audit_dao` | `audit.h2_audit._live_mssn_columns` |
| 3 | `h2_mssn_runs_arc` | ARC MSSN | миграция `0017`; `runtime.mssn_audit_dao` | — |
| 4 | `h2_findings` | находки | `audit.h2_audit.H2Audit.insert_finding` | AVAL Ring 3 (`ai_validation`) |
| 5 | `h2_request_progress` | прогресс запроса | миграция `0060_add_request_progress.sql` | Ring 3 терминальная сверка |
| 6 | `agents_registry` | реестр сервисов (SSOT C-15) | `audit.h2_audit.H2Audit.upsert_agent_registry` | `audit.h2_audit.H2Audit.get_agent_registry`; `cli.probe agents_registry` |
| 7 | `prompts_registry` | промпты (SSOT C-18) | `audit.h2_audit.H2Audit.upsert_prompt` | `llm.prompt_loader.PromptLoader.load`; `cli.probe prompts_registry` |
| 8 | `llm_calls` | LLM-вызовы (C-19) | `audit.h2_audit.H2Audit.insert_llm_call` | `audit.h2_audit.H2Audit.query_llm_logs` |
| 9 | `action_logs` | ACTION-лог (32 колонки) | `db.models.ActionLogsDB.write`; `h2_logging.backends.mysql`; `runtime.log_sink_daemon` | `cli.h2_logs` |
| 10 | `action_types_registry` | реестр типов действий (7 колонок) | seed `h2_logging/seeds/024_action_types_registry.sql` | `h2_logging.sampling.SamplingRegistry` |
| 11 | `agent_checkpoints` | чекпоинты RUN (7 колонок) | `audit.h2_audit.H2Audit.insert_checkpoint`; `run.Checkpoint._write_checkpoint` | — |
| 12 | `llm_logs` | LLM-лог (19 колонок) | `h2_logging.backends.mysql_llm`; `runtime.log_sink_daemon` | `cli.h2_logs` |

**Итого 12 таблиц.** Подробное описание 4 таблиц, ранее не описанных по имени, — в §A3.
Перечень снятых устаревших имён — в §A4.

> Владение записью — исключительно через `h2_shared.sql.H2Audit` (R-05-CENTRAL). Привязка MSSN к
> конкретному сервису (`H2_<agent>_dyn_<corr8>`; имя — канон кода, не переименовывается) — факт
> реестра ADB; разведение схемы таблицы от
> привязки согласовано без расхождения (CONF-ONT-03, `H2_CONTRADICTION_REGISTER_v2.md`).

---

## §7. h2_shared = язык H2 (kernel API + H2_SHARED_CANON 16 R-*-CENTRAL)

### 7.1 Что такое h2_shared
`h2_shared` — Python-пакет (`pip install h2_shared-<version>-py3-none-any.whl`), язык H2: классы и
функции для общения с инфраструктурой (NATS, MariaDB, MinIO, LLM, секреты).

**Текущая фактическая версия по evidence — `0.56.104`** (подтверждено `h2_shared/__version__.py`;
§A2). Wheel публикуется в MinIO `h2-wheels`.

### 7.2 Публичный API (закрытый список — Ring 3)

**Canonical Python API (импорт из `h2_shared`):**
```python
from h2_shared import AgentRuntime, KvBoardClient
from h2_shared import (MssnSpawner, MicrotoolBase, MicrotoolResult,          # 0.56.104 (top-level __all__)
    PersistencePort, Scope, PortError, AuthorizationPort, DistributionObjectPort)
from h2_shared.llm import ResilientLLM
from h2_shared.runtime.transport import send_request, publish_event  # O-2: Ring 3 канал инжекта
from h2_shared.contracts.subjects import (H2_SYSTEM_PING, H2_HEALTH_SNAPSHOT, H2_SYSTEM_TEST,
    SUBJ_DEAD_PID_DETECTED, SUBJ_PROCESS_RESTARTED, SUBJ_ROO_TASK_DRAFT, SUBJ_AGENT_SILENT,
    SUBJ_AGENT_RECOVERED)
from h2_shared.constants import SUBJECT_HEARTBEAT
from h2_shared.utils.standards import VERSION_RE
from h2_shared.logging import observable, observable_async, LogQuery  # LogQuery — только чтение (C-20)
from h2_shared.connection_profiles import secret_present            # только bool, значение не выдаётся
```

**BL-регенерация (Ring 3, h2_shared ≥ 0.56.22):**
```python
kv = KvBoardClient(runtime.transport, board="h2-agent-board")
await kv.put("aval:card", card_json_bytes)
await kv.get("aval:card")
await kv.delete("aval:card")
await runtime.transport.upsert_agent_registry(
    agent_id="aval", card_json=card, live_scenario_path=..., is_active=True)
```

**Helper CLIs (read-only диагностика, вызов через `python -m`):**
- `h2_shared.cli.probe {backend,secrets,audit,nats,agents_registry}` — инфра пробники
- `h2_shared.cli.evidence {query,check-writable,run}` — evidence store CLI (фильтр h2_logs)

**Секреты НЕ публичный API:** `get_secret` существует, но сервисы Ring 3 его не вызывают напрямую —
секреты внутренняя забота h2_shared (§S).

### 7.2a Ring 0-only модули (запрещено импортировать из Ring 3)

| Модуль | Причина | Статус |
|---|---|---|
| `H2Audit` | `h2_shared/__init__.py` docstring явно запрещает импорт из Ring 3; используйте `transport.upsert_agent_registry` (bridge) | RESTRICTED (E-13) |
| `LogQuery` | Публичный API только для чтения (§7.2, C-20) | PUBLIC read-only |
| `NATSClient` | Ring 3 использует `transport.send_request` вместо прямого NATS | RESTRICTED (E-13) |

Ring 3 **MUST NOT** импортировать эти модули. Нарушение = boundary violation F-18..F-23
(см. `RING3_FORBIDDEN_OPS_v1.md`).

### 7.3 Запрещённые импорты для Ring 3
`from h2_shared.secrets import get_secret`; `from h2_shared.internal.*`;
`from h2_shared.runtime.kernel.*`; `import h2_shared._private`.

### 7.5 H2_SHARED_CANON — 16 R-*-CENTRAL правил
| # | Правило | Смысл |
|---|---|---|
| R-01-CENTRAL | единственный wheel на платформу | один источник, никаких форков |
| R-02-CENTRAL | SemVer + SHA256 в `h2_wheels` | пакет верифицируем |
| R-03-CENTRAL | Topology lock встроен (heavy01=infra, laptop=agents) | конфиг не размазан |
| R-04-CENTRAL | NATS subjects = closed list `contracts.subjects` | никаких ad-hoc subjects |
| R-05-CENTRAL | SQL schema = closed list через `H2Audit` | никаких ad-hoc INSERT |
| R-06-CENTRAL | LLM только через `ResilientLLM` | retry/backoff, лог, dedup |
| R-07-CENTRAL | Секреты только через `get_secret` ВНУТРИ h2_shared | сервис не видит секретов |
| R-08-CENTRAL | Heartbeat = sealed `HeartbeatPublisher` | один формат субджекта |
| R-09-CENTRAL | Runtime = sealed `AgentRuntime` | одинаковый жизненный цикл |
| R-10-CENTRAL | MinIO через `h2_canon.minio` | один клиент на всех |
| R-11-CENTRAL | Logging через `h2_logging` | один формат |
| R-12-CENTRAL | Checkers через `h2_shared.checkers` | DRY |
| R-13-CENTRAL | Standards md упакованы в whl `standards/` | верификация версий |
| R-14-CENTRAL | `get_standard_version()` доступен Ring 0 | аудитор знает с чем сравнивает |
| R-15-CENTRAL | Object Store boundaries определены | NATS OBJ vs MinIO явная граница |
| R-16-CENTRAL | KV имена = closed list lowercase-kebab | `h2-agent-board`, не `H2_AGENT_BOARD` |

### 7.7 Ring 0 vs Ring 3 — практическая разница
| Аспект | Ring 0 | Ring 3 |
|---|---|---|
| Импорты | любые модули h2_shared | только публичный API §7.2 (без `get_secret`) |
| Subjects | `h2.>` (все) | только свой LISTEN_SUBJECT + heartbeat |
| KV | любой bucket | только `h2-agent-board` (своя запись) |
| SQL | все 12 таблиц канона | запись через H2Audit; чтение через LogQuery (C-20) |
| Секреты | `get_secret` для аудита | НЕТ; h2_shared тянет секреты внутри |

> Ring 0/Ring 3 здесь — **абстрактная структура доступа** (каноны C-12, C-13). Ring 3 — сервисный
> слой без LLM: бизнес-логика подключений к ИТ-продуктам компании; оркестраторы (ПерпКомп, Roo
> Code) запускают сервисы Ring 3 как готовые тулзы через шлюз ACO. Поимённое отнесение
> конкретных сервисов к кольцам — факт реестра ADB (`list_products`, карточка сервиса).

### 7.8 Durable persistence и аутбокс (публичный контракт, h2_shared ≥ 0.56.104)

`h2_shared.ports.PersistencePort` — публичный порт долговечного хранилища Ring 3 (top-level
`__all__`). Два бэкенда: MariaDB (`h2_shared/ports_durable_mariadb.py`, `H2_DURABLE_BACKEND=mariadb`)
и файловый (`PersistencePort.durable(directory=…)`). Верифицированные сигнатуры (0.56.104):

- `create(product_id, resource_type, record_id, payload, *, scope, environment, schema_version="1", policy_version=None) -> PersistenceRecord`
- `upsert(...)` — те же параметры; `get(product_id, resource_type, record_id, *, scope, environment) -> Optional[PersistenceRecord]`
- `query(product_id, resource_type, *, scope, environment, limit=100) -> list[PersistenceRecord]`
- `compare_and_set(product_id, resource_type, record_id, *, expected_version, new_payload, scope, environment, schema_version="1", policy_version=None) -> PersistenceRecord`
- `delete(...) -> bool`; `create_idempotent(..., idempotency_key, ...) -> PersistenceRecord`; `durable(directory=None) -> PersistencePort`
- Outbox: `append_events(product_id, resource_type, record_id, events, *, scope, environment, expected_version) -> dict`; `claim_outbox(limit=100) -> list[dict]`; `mark_delivered(event_id) -> bool`

`PortError` коды: `UNAVAILABLE`, `INVALID_REQUEST`, `VERSION_CONFLICT`, `NOT_FOUND`, `CONFLICT`.
Координаты `Scope`/`environment` — обязательны. Физическая схема durable-таблиц — миграция
`storage/sql/migrations/0070_add_durable_persistence_tables.sql` (0.56.104).

Публичные фасады Ring 3 уровня `h2_shared.runtime` (не `h2_shared.ports`): managed-KV
(`h2_shared/runtime/managed_kv.py`), Object Store (`h2_shared/runtime/managed_object_store.py`) и
`BrowserProfileStore`. Дополнительно публичны (top-level `__all__`): `AuthorizationPort`,
`DistributionObjectPort`.

> Schema-aware `query_action_logs` (`audit/h2_audit.py`, 0.56.103) и разбор `--since` в CLI `h2-logs`
> (`logs/cli.py`, 0.56.104: относительный `s/m/h/d` либо абсолютный ISO-8601) — публичные
> наблюдаемостные фасады ядра.

---

## §11.7 Dispatch фазы — механизм ядра

Канонический механизм `handle_orchestrated_phase()` в `h2_shared/runtime/orchestrator.py` —
единая точка приёма inbound-запроса для **сервиса Ring 3**. (Кто инициирует и планирует работу —
оркестрация — вне ядра: внешние ИИ-агенты (ПерпКомп, Roo Code) за шлюзом ACO.)

- **11.7.2 Payload (2 обязательных поля):** `request_text` (свободная строка) + `correlation_id`.
  5+ полей = REJECT (C-15 v1.1). Поля `target`/`phase_id`/`checkers[]` удалены (LLM выводит из текста).
- **11.7.3 MSSN-модель (C-01 v1.2):** одна MSSN-запись на весь запрос; микротулзы не создают своих
  MSSN, видны через `h2_logs` (`invoke.ENTER`/`invoke.EXIT`); findings — в `h2_findings` с единым
  `mssn_id`.
- **11.7.4 `run_as_mssn` (canonical shape):** INSERT в `h2_mssn_runs` → загрузка `card_json`/версии
  → исполнение микротулы `run(ctx)` в режиме **plain_run** → финальный UPDATE → reply в NATS →
  NSSM cleanup. Listener только валидирует payload и spawn'ит NSSM.
  **LEGACY-путь (1.7.17):** `PromptLoader.load("agent_orchestrator")` (C-18) → `Orchestrator.run(...)`
  (ReAct-цикл THOUGHT→ACTION→OBSERVATION→FINAL) сохранён только для спец-исполнителей
  (`test_guide`, `ai_validation`, `ai_h2_shared_validation`); для сервисов Ring 3 запрещён —
  регрессия 2026-09-12 (цикл игнорировал `answer` из start.py и возвращал `"echo"`;
  L1 Концепт ACO §0; spawn-контракт `run_mode=plain_run` — Онтология ACO §7).

  **Предпусковая проверка (C-12 Black Box Enforcement):** перед стартом listener
  сервис **MUST** пройти `h2-probe readiness` — composite readiness check:
  ```
  python -m h2_shared.probe readiness --agent <agent> --timeout 30 --json
  ```
  Проверяет: NATS connectivity, JetStream доступность, MariaDB connectivity, секреты доступны.
  Exit 0 = GREEN; иначе — старт listener запрещён.

### §11.7.4a MssnSpawner — canonical Ring 3 API для спавна MSSN сессий

`MssnSpawner` — публичный класс из `h2_shared` (top-level `__all__`), предоставляющий
Сервисам Ring 3 канонический способ спавна динамических MSSN сессий. Статус: **CURRENT**.

- **Назначение:** спавн short-lived NSSM-сервиса `H2_<agent>_dyn_<corr8>` для исполнения
  одной MSSN (C-01 v1.3).
- **Владелец:** h2_shared.runtime (механизм ядра).
- **Ring 3 использует через:** `from h2_shared import MssnSpawner`.
- **Запрещено:** прямой вызов `nssm install` из Ring 3 (F-06, `RING3_FORBIDDEN_OPS_v1.md`).
- **Env-whitelist MSSN:** `MssnSpawner.spawn()` наследует канонический
  5-var whitelist родительского листенера (`H2_AGENT`, `PYTHONPATH`, `AGENT_ROOT`,
  `H2_EVIDENCE_DIR`, `H2_SECRETS_FILE`) и пробрасывает в `AppEnvironmentExtra` дочернего
  MSSN. Fail-fast если `H2_SECRETS_FILE` отсутствует у родителя. Секреты
  (DEEPSEEK_API_KEY etc.) НЕ пробрасываются — MSSN читает их через
  `h2_shared.secrets.get_secret()` используя `H2_SECRETS_FILE`.
  Основание: ESCALATION_D6_MSSN_SECRETS_INHERITANCE_v1 (2026-07-24).

- **11.7.5 LLM-цикл:** `max_iterations = 20`, `max_wall_sec = 1800` (30 min) — единственный
  действующий норматив (CONF-ONT-05, `H2_CONTRADICTION_REGISTER_v2.md`).
  Scratchpad in-memory. Параллелизм BL-регенерации — ответственность валидирующего сервиса Ring 3, не ядра.

> **Публичный Ring 3 API для BL-регенерации (canonical, h2_shared ≥ 0.56.22):**
> - `KvBoardClient.put` / `.get` / `.delete` / `.list_alive` — публикация/чтение `agent_kv_card.md` в KV Board.
> - `AgentRuntime.transport.upsert_agent_registry(agent_id, card_json, live_scenario_path, is_active)` — запись в `agents_registry`.
> - `H2Audit` — Ring 0-only, использовать транспорт-обёртку `transport.upsert_agent_registry`.

> **Reference implementation:** `LIVE_SCENARIO_AI_VALIDATION.md v4.0.1` (агент AVAL, Ring 3) — единственный канонический LIVE_SCENARIO валидирующего агента, реализующий круг BL-регенерации.
- **11.7.6 Reply schema (плоская):** `mssn_id`, `correlation_id`, `total_findings`,
  `blocking_findings`, `status`, `started_at`, `finished_at`, `error_type`, `error_message`.
  Client-timeout = 1800s. Агрегация findings — SQL projection, не in-memory.
- **11.7.7 Поведение при FAIL / 11.7.8 запрет LLM-цикла для сервисов Ring 3 / 11.7.9 файлы:**
  dispatch живёт в `h2_shared/runtime/orchestrator.py` (C-04), без reasoning-цикла для сервисов
  Ring 3; `llm_dispatcher.py`/`macrotool_loop` — не канон, не применяются.

> Справочный список конкретных микротулз AVAL внутри §11.7.4 — факт реестра ADB (карточка сервиса).

---

## §11.8 TOTAL-LOG — механизм ядра

- **11.8.2 Область:** каноны C-16..C-20 применяются ко всем модулям h2_shared и всем сервисам.
  Recursion guard: сам модуль логирования, `LogQuery`, pure-utils — не оборачиваются.
- **11.8.3 Декораторы `@observable`/`@observable_async`** (`h2_shared.logging.observable`):
  захват аргументов через `inspect.signature`; запись `ENTER`/`EXIT`/`ERROR` в `h2_logs`;
  проброс `mssn_id`/`parent_mssn_id`/`correlation_id`/`agent`/`duration_ms` через `contextvars`;
  секреты redacted; полный body LLM-промпта не логируется (только hash+размер).
- **11.8.3b Частота записи:** «каждый вызов» (§11.8.3) выполняется только в
  полном режиме. По умолчанию действует ограничитель: `H2_OBSERVABLE_MIN_INTERVAL_S` (по
  умолчанию `1.0`) — не чаще одной пары ENTER/EXIT в интервал на пару (component, функция);
  вызовы длительностью от `H2_OBSERVABLE_SLOW_MS` (по умолчанию `250` мс) и **все ERROR
  пишутся всегда**. Полный журнал 1:1 — `H2_OBSERVABLE_MIN_INTERVAL_S=0` в окружении процесса
  (для диагностики и живых проб; постоянная установка для служб — решение UEPR пары).
  `H2_OBSERVABLE_HOTPATH_MODE=full|fast` (по умолчанию `full`) управляет объёмом захвата
  аргументов, не частотой. Проверяющий, который считает строки h2_logs, обязан указывать режим.
- **11.8.3c Запись из Ring 3:** модуль продукта Ring 3 оборачивает свои функции
  `@observable`/`@observable_async` из `h2_shared.logging`; строки ENTER/EXIT/ERROR пишет ядро
  (`H2Audit` внутри h2_shared), продукт `H2Audit` не импортирует. `component` строки — имя модуля
  продукта, что отличает строки Ring 3 от строк ядра. Условия записи те же (режим `full`, §11.8.3b).
  Чтение — только `LogQuery` / CLI evidence.
- **11.8.3a Транспорт записи в h2_logs (C-16 дополнение):** единственный путь —
  `@observable` → contextvars → `h2_shared.sql.H2Audit.insert_h2_log(row)` → **прямой INSERT** в
  MariaDB. Запрещены: прямые `h2_log()` вне декоратора, публикация лог-события в NATS, прямой
  `INSERT INTO h2_logs` минуя H2Audit, собственный `logging.Logger`/`print()` в публичных функциях
  (C-17).
- **Каноны-владельцы механизма:** C-16 (Total-Log), C-17 (Thin Client — нормативный владелец
  H2_SHARED_ONTOLOGY: ядро обязано предоставить единственный декоратор/импорт; сервис Ring 3 не делает
  больше одного вызова), C-18 (`PromptLoader` — LEGACY, спец-исполнители), C-20 (`LogQuery` как единственный путь чтения логов).

> Конкретные TLG-чекеры AVAL, применяющие механизм к коду сервиса, — факт реестра ADB
> (карточка сервиса), с REFERENCE на этот механизм.

---

## §S. Secrets Canon

1. **Ring 3 не имеет доступа к секретам.** Ring 3 не передаёт секреты в AppEnvironmentExtra,
   в `.env`, в CLI args, в файлы workspace. Секреты резолвятся исключительно внутри h2_shared.
   Наличие секрета в AppEnvironmentExtra Ring 3 сервиса = **REJECT_FRAUD** (см. §5.3 п.8).

   **H2_SECRETS_FILE.** Для NSSM-сервисов под LocalSystem, где канонический источник
   секретов недоступен или зависает (hard-timeout), Ring 0 оператор создаёт файл секретов,
   доступный только SYSTEM.

   - Путь к файлу передаётся через env-переменную `H2_SECRETS_FILE`
     (whitelist NSSM, Guide §7.3).
   - Формат файла, ACL, точный список полей — см. `H2_SHARED_INTERNALS_OPERATIONS.md`
     (Ring 0-only, не читается сервисами Ring 3).
   - Ring 3 знает **только имя переменной** `H2_SECRETS_FILE`; значение переменной,
     путь, содержимое файла и список ключей — Ring 3 не читает.
   - h2_shared читает файл внутри пакета, содержимое не логируется.

2. **Discovery chain** (внутри h2_shared) — детали реализации в `H2_SHARED_INTERNALS_OPERATIONS.md`
   (Ring 0-only). Ring 3 знает только: секреты резолвятся автоматически, порядок гарантирован,
   hard-timeout предотвращает зависание.

3. **Закрытый список ключей** секретов — определён в `H2_SHARED_INTERNALS_OPERATIONS.md`
   (Ring 0-only). Ring 3 не знает имён ключей и не должен встречать их в SSOT-документах.
   Добавление нового секретного ключа — задача релиза h2_shared, не Ring 3.

4. **Async-контекст.** Из синхронного кода (bootstrap scripts, CLI утилиты) используется
   синхронная точка входа. Из async-контекста (listener handler, mssn_spawner, любой `async def`) —
   только async-точка входа. Детали API — см. публичную поверхность h2_shared.

5. **Hard-timeout.** При недоступности канонического источника секретов
   срабатывает hard-timeout (настраивается через env, default 10s). После первого
   hard-timeout канонический источник пропускается до конца жизни процесса.
   Предотвращает зависание >60s под elevated SYSTEM-контекстом (NSSM/UAC).

6. **Граница колец по импортёру.** Ring 0-модули ядра (`h2_shared.secrets`,
   `h2_shared.audit`, `h2_shared.nats`) проверяют того, КТО их импортирует. Импорт из модуля ядра
   (в том числе ленивый — внутри публичной функции, вызванной продуктом Ring 3) разрешён: секрет
   читает само ядро от своего имени, значение наружу не выдаётся. Прямой импорт из кода продукта —
   `RingBoundaryError`, даже если выше в стеке есть доверенный кадр. `RingBoundaryError` никогда не
   превращается в «секрета нет»: он пробрасывается; в `False` / `PROFILE_SECRET_MISSING` переходят
   только настоящие сбои резолвинга. Ring 3 узнаёт о наличии секрета только булевым значением
   (`secret_present(alias)`, поле `secret_resolvable` профиля).

---

## §M. MSSN Admin Context

**Терминологическое различение (не изменение норм):** **MSSN** — это *запись/прогон миссии*
(одна обработка запроса от inbound до reply), фиксируемая строкой в `h2_mssn_runs` (канон C-01);
это логическая сущность, не служба. **NSSM** — *Windows service manager* (Non-Sucking Service
Manager), инфраструктурный инструмент ОС, которым `h2_shared` устанавливает/запускает/
останавливает службы Windows. Связь: каждая MSSN исполняется внутри отдельного динамического
NSSM-сервиса, имя которого включает/соответствует `mssn_id` (`H2_<agent>_dyn_<corr8>`, §5.3).
Термины не взаимозаменяемы.

Каждый MSSN имеет admin-context для отладки: `pid`, `host_id`, `started_at`, `last_heartbeat`.
Доступен через `h2_audit.h2_mssn_runs`. **MSSN_TTL_SEC** = 600 по умолчанию; reaper
`mssn_global_reaper` (owner: `h2_shared.sql.H2Audit` background-task) раз в 60с помечает просроченные
`status='timeout'`.

---

## §K. AgentRuntime NATS-стратегия

### K.1 Стратегия подключения
`h2_shared.runtime.AgentRuntime` использует **one-URL стратегию**: один URL для core NATS и
JetStream. При `ServiceUnavailable` на JetStream-операциях — сервис продолжает работу без heartbeat
в KV (graceful degradation); core NATS pub/sub остаётся функциональным.

### K.2 Канонический URL
Production: `NATS_URL=nats://192.168.99.11:4222` (heavy01). Тесты (без JetStream):
`nats://127.0.0.1:4223`.

### K.3 Канонический host-level конфиг

- **Источник host-конфигурации — `C:\ProgramData\H2\config\node.json`** (см. §K.4).
  `AgentRuntime.host_config()` читает из него: `nats.connection_profile_ref` (серверы),
  `nats.subject_namespace` (домен), `connection_profiles.sql` (хост MariaDB), `paths.logs_root`.
- **Явный параметр `nats_url`** в `AgentRuntime.__init__` — override для тестов.
- **Fail-fast валидация JetStream при старте** — если активный профиль не heavy01 и не задан
  явный override, ping JetStream и аварийно выйти с чётким сообщением.
- **Документирование one-URL стратегии** в §7.2 (публичный API).

### K.4 Канонический `node.json` — host-level SSOT

**Канонный путь:** `C:\ProgramData\H2\config\node.json` (константа `CANONICAL_NODE_JSON`
в `h2_shared/install.py` L48). Это **host-level SSOT конфигурации ноды**. Файл создаётся
деплойным процессом извне репозитория; в открытом коде h2_shared writer отсутствует
(признак: множество бэкапов с идентичным sha256, поле `compatibility.mode =
"legacy_shim_required"`).

**Читатели (закрытый список):**

1. `h2_shared.install.py` L196 — CLI-валидатор `h2_shared install --node-json <path>`
   (default = `CANONICAL_NODE_JSON`).
2. `h2_shared.node_config.load_node_config(path=None) -> NodeConfig` — публичный API
   Ring 3 и Ring 0. Сервисы Ring 3 **не читают файл напрямую**; только через этот API.
3. `h2_shared.node_config.validate_node_config(cfg) -> None` — публичный API валидации
   схемы.
4. `ai_h2_shared_validation.node_checks.ring0_static` L155 — regex-валидатор,
   проверяет отсутствие прямых обращений к пути в коде.
5. `ai_h2_shared_validation.node_checks.gates_common` L36/L145/L247 — Ring 0 гейт G2:
   «никто в коде не должен обращаться к `ProgramData/H2/config/node.json` напрямую,
   только через `h2_shared.node_config.*`».

**Первая проверка UEPR.** UEPR любого узла начинается с проверки `node.json` по этому
канону (Гайд UEPR, координаты: `{"op":"get_document","env":"prod","product":"h2_shared",
"doc_type":"Гайд UEPR","latest":true}`). Проверка выполняется через публичный API
`h2_shared.node_config` (`load_node_config`/`validate_node_config`), без правки файла.

**Схема (закрытый список полей, schema_version=1):**

```
{
  "schema_version": 1,
  "config_id": "<uuid>",
  "config_revision": <int>,
  "node_id": "<heavy01|heavy02|laptop|light01|light02|...>",
  "role": "h2-node",
  "paths": {
    "programdata_root": "C:\\ProgramData\\H2",
    "h2_root": "C:\\h2",
    "bridge_home": "C:\\h2\\h2_shared",
    "logs_root": "C:\\h2\\h2_shared\\logs",
    "evidence_root": "C:\\h2\\h2_shared\\evidence",
    "log_sink_root": "C:\\h2\\h2_shared\\logs\\log_sink",
    "mariadb_data_root": "C:\\h2\\h2_shared\\data\\mariadb",
    "roo": {
      "storage_root": "C:\\h2\\h2_shared\\roo",
      "tasks_root": "C:\\h2\\h2_shared\\roo\\tasks",
      "instances_registry": "C:\\h2\\h2_shared\\roo\\instances.json"
    }
  },
  "nats": {
    "connection_profile_ref": "h2-nats-prod",
    "subject_namespace": "h2",
    "heartbeat_template": "h2.health.heartbeat.{node_id}"
  },
  "service": {
    "name": "H2_<NODE>_BRIDGE_SVC",
    "manager": "nssm",
    "run_as": {"sid": "S-1-5-18", "account_name": "NT AUTHORITY\\SYSTEM"}
  },
  "limits": {
    "max_command_bytes": 262144,
    "max_ws_frame_bytes": 262144,
    "max_export_bytes": 33554432,
    "max_bridge_rss_mb": 1024,
    "max_log_file_bytes": 10485760,
    "max_log_file_count": 10
  },
  "compatibility": {
    "legacy_config_path": "<path>",
    "legacy_bridge_version": "<version|none>",
    "migration_source_sha256": "<hex>",
    "mode": "legacy_shim_required|native"
  },
  "integrity": {
    "canonicalization": "RFC8785-JCS-excluding-integrity.canonical_payload_sha256",
    "canonical_payload_sha256": "<hex>"
  },
  "connection_profiles": {
    "nats": "h2-nats-prod",
    "sql": "h2-sql-audit",
    "llm": "h2-llm-default",
    "owui": "h2-owui",
    "log_sink": "h2-log-sink"
  },
  "object_store": {
    "artifact_kv": {
      "buckets": ["h2-artifacts"],
      "max_bytes": 67108864,
      "kv_put_timeout_s": 5.0,
      "kv_get_timeout_s": 5.0,
      "capability_ttl_s": 300.0,
      "connection_profile_ref": "h2-nats-prod"
    }
  }
}
```

**Инварианты (закрытый список):**

1. **Отсутствие секретов.** В `node.json` НЕТ полей `*password*`, `*secret*`, `*token*`,
   `*key*`. Секреты живут исключительно в `H2_SECRETS_FILE` (§S п.1).
2. **Отсутствие явных инфраструктурных адресов.** URL NATS, DSN MariaDB, IP-адреса
   кластера **НЕ** хранятся в `node.json`. Хранятся только **ссылки на профили**
   (`connection_profiles.*`, `nats.connection_profile_ref`). Резолвинг профиля в
   конкретный URL — обязанность `h2_shared.node_config` / `AgentRuntime.host_config()`.
3. **Отсутствие `workspace_root`.** В файле НЕТ поля `workspace_root`. Пути папок Roo
   фиксируются в `paths.roo.storage_root`, `paths.roo.tasks_root`, `paths.roo.instances_registry`.
4. **Integrity.** `integrity.canonical_payload_sha256` вычисляется по JCS RFC8785
   исключая **только поле** `integrity.canonical_payload_sha256` (сам блок `integrity`
   с остальными полями, например `canonicalization`, остаётся в canonicalized payload).
   Реализация: `h2_shared.node_config.schema.compute_canonical_payload_sha256()`.
   Валидатор пересчитывает hash и сравнивает с записанным. Верификация подтверждена
   на heavy02 (2026-09-09): computed = recorded = `d91650925bf9b7c10fc74d7f86efd0300d8e30c338241431339827686a0c4288`.
5. **Compatibility mode.** `compatibility.mode = "legacy_shim_required"` означает, что
   деплойный процесс использует legacy-shim; `"native"` — прямая установка.
6. **Множественность экземпляров.** На ноде допустимы дополнительные `node.json` в
   `bridge_work\deploy_*` (stage-конфиги), `evidence\*\rollback` (бэкапы), `incoming\h2_shared_*`
   (release-pack'и). SSOT — **только** `C:\ProgramData\H2\config\node.json`.

**Запреты:**

- Сервисы Ring 3 **НЕ** читают `node.json` напрямую (`open()`, `json.load()`). Только через
  `h2_shared.node_config.load_node_config()`.
- Прямые обращения к пути `C:\ProgramData\H2\config\node.json` в коде запрещены
  (гейт G2 в `ai_h2_shared_validation.node_checks.gates_common`). Исключения: сам
  `h2_shared.install` (CLI-валидатор) и `h2_shared.node_config` (публичный API).
- ADB **НЕ** дублирует поля из `node.json`. Продуктовые расширения (accounts, autostart,
  secrets_manifest, firewall, watchdogs, registry) хранятся в отдельных JSON-профилях ADB
  и **ссылаются** на `node_id` из `node.json`.

## §2a-shared. Каноны, чьим нормативным владельцем является H2_SHARED_ONTOLOGY (11 канонов)

Полная таблица владения 22 канонов — в `H2_CONTRADICTION_REGISTER_v2.md` §1/§2 (для OPEN/RESOLVED)
и в `H2_DOCUMENTATION_SSOT_INDEX_v2_7.md` (канон-каталог). Определения канонов ниже сохранены дословно из
`H2_ONTOLOGY_v5_7.md` §2.5.2, без изменения ID/версии/смысла.

| Канон | Имя | Версия | Определение (дословно из источника) |
|---|---|---|---|
| C-01 | MSSN-канон | 1.3 | Каждая обработка inbound NATS-сообщения = отдельный short-lived NSSM `H2_<agent>_dyn_<corr8>`, spawn через `MssnSpawner`, cleanup после reply; MSSN-запись в `h2_mssn_runs`. C-01 v1.3: session-long MSSN только для агента с `mssn_lifecycle="session"`. |
| C-03 | NATS-дисциплина | 1.0 | Все subjects только через `h2_shared.contracts.subjects.*`. Hardcoded строки в агентском коде = FAIL. |
| C-04 | h2_shared = SSOT | 1.0 | 16 R-*-CENTRAL правил: NATS/KV/SQL/MinIO/secrets/logging/evidence/contracts/agent_card — только через h2_shared. Дубли = FAIL. |
| C-08 | KV-Board канон | 1.0 | `h2-agent-board` (lowercase-kebab) — единственная live-доска состояния агентов. Другие KV-доски = legacy. |
| C-12 | Black Box principle | 1.0 | Ring 3 видит только публичный API `h2_shared.contracts.*` и `h2_shared.runtime.*`. Импорт internals = FAIL. |
| C-13 | Ring 0 / Ring 3 канон | 1.0 | Ring 0 = полный доступ к internals; Ring 3 = только публичный API. (Запись канона в реестре не называет агентов поимённо.) |
| C-15 | Orchestration canon | 1.2 | Единственная точка dispatch — `handle_orchestrated_phase()` в h2_shared. Прямой вызов микротулзы минуя LLM запрещён; hardcoded `asyncio.gather` = нарушение. |
| C-16 | Total-Log канон | 1.0 | Каждая публичная функция обязана быть декорирована `@observable`/`@observable_async`. Исключения: модуль логирования, mssn_context (рекурсия). |
| C-17 | Thin Client канон | 1.0 | Логирование/MSSN-контекст/lockdown — kernel-обязанность h2_shared. На стороне агента — один декоратор/импорт. Ручные `logger.info` с дублированием context-полей запрещены. **Нормативный владелец — H2_SHARED_ONTOLOGY**; Builder Guide только практически объясняет границу. |
| C-18 | Prompt Loading канон | 1.1 | Любой промпт — только через `PromptLoader.load(name, version)` из `prompts_registry`. Filesystem/inline/KV/NATS/env — запрещены. |
| C-20 | LogQuery as Kernel API | 1.0 | Поиск/агрегация по логам — только через `h2_shared.logging.LogQuery` и CLI `h2-logs`. Прямые SQL-запросы вне kernel запрещены. Запись — через H2Audit, LogQuery только read. |

**Каноны, определяемые стандартами (REFERENCE, текст не дублируется здесь):** C-10 → STANDARD_WORKSPACE_HYGIENE; C-11 → STANDARD_MAS; C-14 → STANDARD_AFAD.
**Каноны REGISTER-CONFLICT (владелец не назначен):** C-19 (Log-First Diagnosis), C-21 (Single-Author Single-Validator) — см. CONF-ONT-08.
**Каноны сервисного слоя (вне этого документа):** C-02, C-05, C-06, C-07, C-09, C-22.

**Проверка арифметики:** 11 (shared) + 6 (сервисного слоя) + 3 (стандарты) + 2 (OPEN) = **22**.

> **Статус C-15/C-18 (правка 1.7.17):** определения канонов выше сохранены дословно из
> исторического источника. Фактическая модель: C-15 — dispatch остаётся единой точкой приёма,
> но без LLM-цикла для сервисов Ring 3; C-18 — канон загрузки промптов, применяется только
> спец-исполнителями. Сервисы Ring 3 работают в `run_mode=plain_run` без промптов
> (Онтология ACO §7; L1 Концепт ACO §0).

---

## §А.1-agents.norm — норма создания новых сервисов только по Guide (владелец)

**Все новые сервисы Ring 3 платформы H2 создаются только по Гайду Пользователя h2_shared** —
единственный boundary contract; координаты ADB:
`{"op":"get_document","env":"prod","product":"h2_shared","doc_type":"Гайд Пользователя","latest":true}`.
(Историческая формулировка — `ROADMAP_H2_FULL_PLATFORM_LAUNCH_AND_PROOF_v1` §6.5 п.3.)

- **Владелец нормы:** этот документ (`H2_SHARED_ONTOLOGY`). Зеркальная запись — факт реестра ADB
  (продукт, документ типа Guide, REFERENCE-подтверждение).
- **Постоянные методологические спец-исполнители (roadmap §6.5 п.1–2), фиксируемые additive-фактом здесь:**
  - **`test_guide`** — постоянный регрессионный агент для каждой новой версии `h2_shared`. Не
    удаляется после разового использования (roadmap §6.5 п.1).
  - **`ai_h2_shared_validation`** — обязательный постоянный агент независимой валидации `h2_shared`.
    Не опционален (roadmap §6.5 п.2).
  - Полное определение ролей/микротулз этих двух спец-исполнителей — предмет карточек сервисов
    (реестр ADB); здесь зафиксирован только факт постоянства и
    обязательности как норма уровня ядра/владения.
- **Проверяемый гейт (историческая формулировка Roadmap §6.5 п.3; зеркальная ссылка с 1.7.17 —
  реестр ADB):** «проверяемым гейтом в Roadmap, правилом контроля в AVAL».

---

## §14. Generic input/result (нормативная секция)

Нормативный блок generic input/result — **единственный владелец H2_SHARED_ONTOLOGY**. Состав полей
фиксируется **по факту публичного API** со ссылкой на evidence.

### 14.1 Владение

Единственный нормативный владелец схемы `MicrotoolResult`/generic input — этот документ. Guide
ссылается сюда по REFERENCE, не переопределяет состав полей самостоятельно.

### 14.2 Состав полей (по факту `h2_shared/contracts/microtool_interface.py:54`, 0.56.104)

Фактический публичный контракт `MicrotoolResult` — **8 полей**:

- `microtool_id` — идентификатор микротулза;
- `trace_id` — идентификатор трассировки (correlates с `correlation_id`);
- `status` — строковый статус (`OK` / `FAIL` / `ERROR`);
- `findings` — список находок (`List[MicrotoolFinding]`);
- `started_at` — время старта (datetime);
- `finished_at` — время завершения (datetime);
- `duration_ms` — длительность в миллисекундах;
- `error` — описание ошибки (`Optional[str]`).

> Состав (8 полей) подтверждён **de facto** в `h2_shared/contracts/microtool_interface.py:54`
> (0.56.104). Нормативный владелец состава — этот документ +
> `h2_shared/contracts/microtool_interface.py`. Кодер **MUST NOT** расширять состав без новой
> версии этой секции.

### 14.3 Generic input

Универсальная сигнатура вызова микротулзы — `async def run(ctx: MicrotoolContext, input: TInput) ->
TOutput`, где `TOutput` соответствует §14.2. `MicrotoolContext` — практический boundary-факт,
переносимый из Guide без изменения (см. Guide §5).

### 14.4 Evidence-ссылка (обязательна согласно §6.7 п.4 roadmap)

Состав §14.2 подтверждён **не голым числом/списком без источника**, а следующим evidence:
run `AVAL-2C-20260716-101307-e79adc53`, ACCEPT verdict `PMA_H2_AVAL_ITERATION_2C_G4_ACCEPT_v1`,
h2_shared wheel 0.56.104 (`h2_shared/__version__.py`),
h2_shared `contracts/microtool_interface.py:54`.

---

## §15. Capability Manifest (final, post-G4)

Согласно `ROADMAP_H2_FULL_PLATFORM_LAUNCH_AND_PROOF_v1` §6.4 п.10: финальный публичный capability
manifest `h2_shared` по факту Ф4 (не draft), с REFERENCE на `test_guide` regression-контракт.

### 15.1 Статус манифеста

**FINAL** (не draft) — зафиксирован по факту прохождения гейта G4 (Ф4, финальный regression AVAL).
Отличается от «проектного (draft) артефакта», производимого на промежуточных фазах (терминология
§17 глоссария `ROADMAP_H2_SHARED_THREE_CODER_PROOF_v1_1`: draft vs final).

### 15.2 Состав

- **Публичный API (Ring 3):** §7.2 этого документа — `AgentRuntime`, `KvBoardClient`,
  `ResilientLLM`, `transport.send_request`/`publish_event`, `MssnSpawner`, `MicrotoolResult`,
  `MicrotoolBase`, `contracts.subjects.*`, `constants.SUBJECT_HEARTBEAT`,
  `utils.standards.VERSION_RE`, CLI `h2_shared.cli.probe`, CLI `h2_shared.cli.evidence`,
  `h2-probe readiness`; durable persistence (§7.8, 0.56.104) — `PersistencePort`, `Scope`,
  `PortError`, `AuthorizationPort`, `DistributionObjectPort`.
- **Generic input/result:** §14 этого документа (владелец — этот документ; 8 полей).
- **Версия/SHA ядра:** h2_shared **0.56.104** (подтверждено `h2_shared/__version__.py`; §A2).

### 15.3 REFERENCE на test_guide regression-контракт

Регрессионный контракт постоянного агента `test_guide` (roadmap §6.5 п.1) — предмет будущей PMA
на фазе Ф6/G6 (roadmap §7 RACI); этот манифест ссылается на него как на будущий обязательный
контроль для каждой новой версии `h2_shared`, не переопределяя его содержание здесь (не входит в
явный перечень правок §6.4/§6.5 этого DOC-1 — только REFERENCE-заготовка).

---

## §F. Инварианты Ring 3

Дополнительные инварианты Ring 3:

**F.N+1** — Сервис Ring 3 **НЕ** инсталлирует h2_shared через `pip install` — только через
bundle `install.ps1` (bundle SHA-verified). Это исключает повторное прохождение 5 PMA
на установку deps и гарантирует bit-identical окружение.

**F.N+2** — Ring 3 PMA-скрипт **ВСЕГДА** self-elevates до Administrator перед §P-0
preflight. NSSM install/start/remove требует admin; без elevation скрипт упадёт на
`nssm install` с `Access denied`. Канонический self-elevation блок — см. §C7.3.

**F.N+3** — Ring 3 preflight **ВСЕГДА** использует Python-socket NATS-check, не
`Test-NetConnection`. `Test-NetConnection` в elevated PowerShell ненадёжен (Windows
network profiles). Каноническая проверка — см. §C7.4.

**F.N+4** — Ring 3 PMA-скрипт **НЕ** содержит явных адресов NATS / MariaDB / любых
инфраструктурных хостов. Все connectivity/evidence проверки — через
h2_shared CLI-утилиты, читающие host-level конфиг (§K.4).

---

## §S. MSSN Secrets Propagation

### SecS. MSSN Secrets Propagation

**Канонический механизм передачи secrets в MSSN.**

1. **Listener -> MssnSpawner:** родительский listener получает H2_SECRETS_FILE через NSSM AppEnvironmentExtra.
   `MssnSpawner.spawn()` пробрасывает H2_SECRETS_FILE в дочерний MSSN если он доступен в `os.environ`.

2. **MSSN secrets resolution (4-tier fallback):** если H2_SECRETS_FILE не установлен в окружении MSSN,
   secrets модуль резолвит через канонический 4-tier chain:
   - Tier 1: NATS KV `h2-secrets`
   - Tier 2: H2_SECRETS_FILE (файл на диске)
   - Tier 3: переменные окружения (`DEEPSEEK_API_KEY` etc.)
   - Tier 4: `.env` файл

3. **Fail-closed:** при невозможности получить обязательный секрет (`mariadb_audit_url`, `deepseek_api_key`)
   MSSN завершается с ошибкой. Частичная деградация запрещена.

4. **Secrets safety:** значения секретов не записываются в:
   - agent_card.json или agent_kv_card.md,
   - логи (stdout/stderr/h2_logs),
   - evidence (request/reply/NSSM env dump),
   - CLI аргументы,
   - переменные окружения MSSN (кроме H2_SECRETS_FILE — путь к файлу, не содержимое).

5. **Scope:** механизм единый для всех сервисов Ring 3 (AVAL, test_guide, ASHV, ADR, H2H).
   Agent-specific monkey-patch или обход через agent_card запрещён.

---

## §A1. implementation_contract

Непустой блок `implementation_contract` — обязателен для dev-Онтологии (Guide UEPR,
раздел «Минимальный контракт Онтологии»). Каждая строка — ровно четыре поля: `name`,
`source_anchor`, `expected_observable`, `verification` (одно из `static_read` | `existing_test` |
`live_scenario`). Все `source_anchor` проверены **фактическим наличием** в установленном пакете
h2_shared **0.56.104** (dev-venv light02).

```yaml
implementation_contract:
  - name: "public read-only log query (LogQuery)"
    source_anchor: "h2_shared/logs/query.py"
    expected_observable: "import h2_shared.logging.LogQuery; LogQuery.tail(component,n) / by_correlation_id(cid) return rows from h2_audit.h2_logs (read-only, C-20)"
    verification: "static_read"
  - name: "prompt loading from MariaDB SSOT (PromptLoader.load)"
    source_anchor: "h2_shared/llm/prompt_loader.py"
    expected_observable: "PromptLoader.load(prompt_id, version='latest') returns Prompt from prompts_registry (C-18)"
    verification: "static_read"
  - name: "agent registry recording (H2Audit.upsert_agent_registry)"
    source_anchor: "h2_shared/audit/h2_audit.py"
    expected_observable: "upsert row into h2_audit.agents_registry incl. card_sha256 (Ring 0 API)"
    verification: "static_read"
  - name: "infrastructure probe CLI"
    source_anchor: "h2_shared/cli/probe.py"
    expected_observable: "python -m h2_shared.cli.probe backend -> JSON with {nats,audit,secrets} booleans"
    verification: "live_scenario"
  - name: "read-only evidence SQL query (C7.2)"
    source_anchor: "h2_shared/evidence/query.py"
    expected_observable: "python -m h2_shared.evidence.query \"SELECT ...\" --format json -> JSON rows on stdout, diagnostics on stderr"
    verification: "live_scenario"
  - name: "public request/reply transport for ADB broker operations"
    source_anchor: "h2_shared/runtime/transport.py"
    expected_observable: "send_request(subject,payload) performs NATS request/reply used by get_document/list_documents/register_document/append_agent_work_log"
    verification: "static_read"
  - name: "NATS endpoint resolution for ADB clients"
    source_anchor: "h2_shared/nats_client.py"
    expected_observable: "get_nats_servers() returns the canonical NATS endpoints used by ADB client calls"
    verification: "static_read"
  - name: "RUN checkpoint persistence (agent_checkpoints)"
    source_anchor: "h2_shared/run/__init__.py"
    expected_observable: "Checkpoint._write_checkpoint inserts into h2_audit.agent_checkpoints (ON DUPLICATE KEY UPDATE)"
    verification: "static_read"
  - name: "node config loader (h2_shared.node_config)"
    source_anchor: "h2_shared/node_config/loader.py"
    expected_observable: "load_node_config(path=None) -> NodeConfig; без явного пути читается только канонический C:/ProgramData/H2/config/node.json с инвариантом H2_NODE_CONFIG"
    verification: "static_read"
  - name: "node config schema validator (h2_shared.node_config)"
    source_anchor: "h2_shared/node_config/schema.py"
    expected_observable: "validate_schema(data) проверяет схему v1 (schema_version, node_id, paths, nats, connection_profiles, integrity)"
    verification: "static_read"
  - name: "node config integrity hash computer (h2_shared.node_config)"
    source_anchor: "h2_shared/node_config/schema.py"
    expected_observable: "compute_canonical_payload_sha256(data) -> sha256 от JCS-канонического JSON после удаления integrity.canonical_payload_sha256"
    verification: "static_read"
```

Сводка (11 строк, min 6 по заданию):

| # | name | source_anchor | verification |
|---|---|---|---|
| 1 | public read-only log query (LogQuery) | `h2_shared/logs/query.py` | static_read |
| 2 | prompt loading (PromptLoader.load) | `h2_shared/llm/prompt_loader.py` | static_read |
| 3 | agent registry recording | `h2_shared/audit/h2_audit.py` | static_read |
| 4 | infrastructure probe CLI | `h2_shared/cli/probe.py` | live_scenario |
| 5 | read-only evidence query | `h2_shared/evidence/query.py` | live_scenario |
| 6 | transport request/reply (broker ops) | `h2_shared/runtime/transport.py` | static_read |
| 7 | NATS endpoint resolution | `h2_shared/nats_client.py` | static_read |
| 8 | RUN checkpoint persistence | `h2_shared/run/__init__.py` | static_read |
| 9 | node config loader | `h2_shared/node_config/loader.py` | static_read |
| 10 | node config schema validator | `h2_shared/node_config/schema.py` | static_read |
| 11 | node config integrity hash computer | `h2_shared/node_config/schema.py` | static_read |

---

## §A2. Явно объявленные текущие факты версии

Guide UEPR требует, чтобы явно объявленные в Онтологии текущие deploy/wheel/версия/SHA
совпадали с read-only картой. Фактическая карта (dev light02, read-only):

| Параметр | Значение |
|---|---|
| Активный deploy | **195** |
| wheel_id / версия | **233 / 0.56.104** |
| wheel SHA-256 | `699741dcd44d71e9b88f9ff256439bc2b8ac08e4a0fb2301f67128843e65b776` |
| Установленный пакет (venv) | 0.56.104 |

---

## §A3. Таблицы канона

Таблицы существуют в БД и код-каноне; код-владельцы подтверждены статическим чтением
пакета h2_shared 0.56.104 (grep `INSERT INTO ...`).

| Таблица | Назначение | Writer (модуль.функция) | Reader | Миграция/схема |
|---|---|---|---|---|
| `action_logs` (32 колонки) | ACTION-лог действий сервисов | `db.models.ActionLogsDB.write`; `h2_logging.backends.mysql`; `runtime.log_sink_daemon` | `cli.h2_logs` | `db/schema/action_logs.sql`; migrations `0021`, seeds `021/023` |
| `action_types_registry` (7 колонок) | реестр типов действий (sampling-правила) | seed `h2_logging/seeds/024_action_types_registry.sql` | `h2_logging.sampling.SamplingRegistry` | `db/schema/action_logs.sql`; seed `024` |
| `agent_checkpoints` (7 колонок) | чекпоинты RUN (`rid,seq,operation,payload_hash,status`) | `audit.h2_audit.H2Audit.insert_checkpoint`; `run.Checkpoint._write_checkpoint` | — (append-only) | `0020_add_agent_checkpoints.sql` |
| `llm_logs` (19 колонок) | LLM-лог (LLM-ось логирования) | `h2_logging.backends.mysql_llm`; `runtime.log_sink_daemon` | `cli.h2_logs` | `db/schema/llm_logs.sql`; `0022_upgrade_llm_logs.sql` |

> `llm_calls` (канон §6, 20 живых колонок) — отдельная таблица C-19; `llm_logs` — legacy-ось
> логирования LLM. Обе присутствуют в БД и имеют код-владельцев.

---

## §A4. Инвентарь таблиц: канон = 12

Живая БД `h2_audit` (read-only, dev light02) и канон пакета 0.56.104 (migrations `0017`–`0070` +
`db/schema/*` + `h2_logging/seeds/024`) дают **ровно 12 таблиц** (см. §6). Миграция `0070`
(durable persistence) добавляет физические таблицы аутбокса/durable-хранилища вне канона 12
(их владелец — `PersistencePort`, а не SQL-канон §6).

Канон (12): `action_logs`, `action_types_registry`, `agent_checkpoints`, `agents_registry`,
`h2_findings`, `h2_logs`, `h2_mssn_runs`, `h2_mssn_runs_arc`, `h2_request_progress`, `llm_calls`,
`llm_logs`, `prompts_registry`.

---

## §A5. owui_functions — функции/операции h2_shared, доступные через OWUI

Блок `owui_functions` (Guide UEPR v0.20). h2_shared **не регистрирует** собственных HTTP-endpoint
в OWUI; публичная поверхность продукта доступна в OWUI косвенно: (i) через ADB-брокер
(`ai_docs_broker`, subject `h2.ai_docs_broker.request`), клиентом которого выступает h2_shared
(`h2_shared.nats_client` + `h2_shared.runtime.transport`), и (ii) через CLI/evidence-фасады.

| Функция/операция | Назначение | code_owner (модуль.функция) | Статус |
|---|---|---|---|
| `get_document` | получить документ из реестра ADB | `h2_shared.runtime.transport.send_request` (client) | served (client-side, ADB) |
| `list_documents` | список документов реестра ADB | `h2_shared.runtime.transport.send_request` (client) | served (client-side, ADB) |
| `register_document` | регистрация нового документа | `h2_shared.runtime.transport.send_request` (client) | served (client-side, ADB) |
| `append_agent_work_log` | запись в журнал работ | `h2_shared.runtime.transport.send_request` (client) | served (client-side, ADB) |
| `list_agent_work_log` | чтение журнала работ | `h2_shared.runtime.transport.send_request` (client) | served (client-side, ADB) |
| `probe backend/secrets/audit/nats` | инфра-пробы | `h2_shared.cli.probe.main` | served (CLI) |
| `evidence query` | read-only SQL-запрос к h2_audit (C7.2) | `h2_shared.evidence.query.run_query` | served (CLI) |
| `get_nats_servers` | резолвинг NATS endpoint | `h2_shared.nats_client.get_nats_servers` | served (library) |

> Endpoint-координата факта: ADB subject `h2.ai_docs_broker.request`; CLI-координаты —
> `python -m h2_shared.cli.probe ...` и `python -m h2_shared.evidence.query ...`.

## §A6. Зачётный Live Scenario

Зачётный живой сценарий (Live Scenario) пакета `h2_shared` адресуется координатами ADB и связан
с текущей версией/кандидатом и SHA.

```yaml
report_document_contract:
  product: h2_shared
  env: dev
  exec_node: light02
  executor: test_guide
  mode: read-only
  ls_document:
    op: get_document
    coordinates: {env: dev, product: h2_shared, doc_type: "Live Scenario", latest: true}
  creditable_result:
    command: "test_guide live --read-only"
    h2_node_config: "C:\ProgramData\H2\config\node.json"
    interpreter: "C:\ProgramData\H2\h2_shared_dev\venv\Scripts\python.exe"
    generated_at: "2026-09-24T11:26:06.143Z"
    report_artifact: "live_report_h02_v4.json"
    report_sha256: "70c966d353ecfbfb37d2463cd46d1caca5a3b700df89e7937377f1aa524f1c4d"
    cases_total: 13
    pass_count: 13
    fail_count: 0
    skip_count: 0
    na_count: 0
    external_observations:
      mariadb: PASS
      nodeconfig: PASS
      sql_facade: PASS
      external_consumer: PASS
  bound_candidate:
    package_version: "0.56.104"
    wheel_id: 233
    wheel_sha256: "699741dcd44d71e9b88f9ff256439bc2b8ac08e4a0fb2301f67128843e65b776"
    deploy_id: 195
  reference_guide:
    op: get_document
    env: prod
    product: h2_shared
    doc_type: "Гайд UEPR"
    latest: true
```

**Координаты зачётного LS-документа.** LS адресуется
`op=get_document, env=dev, product=h2_shared, doc_type=Live Scenario, latest=true`.

**Зачётный результат (dev, read-only).** Прогон `test_guide live --read-only` на узле light02/dev с
`H2_NODE_CONFIG=C:\ProgramData\H2\config\node.json` дал **13/13 PASS** (fail=0, skip=0, na=0) и
**4/4** внешних наблюдения `mariadb`, `nodeconfig`, `sql_facade`, `external_consumer` — `PASS`.
Отчёт — `live_report_h02_v4.json`, sha256
`70c966d353ecfbfb37d2463cd46d1caca5a3b700df89e7937377f1aa524f1c4d` (из фактических байтов),
`generated_at=2026-09-24T11:26:06.143Z`. LS-прогон v4 (test_guide 24/24, CT-01..CT-13 13/13)
привязан к текущему кандидату волны WHEEL104: пакет `0.56.104`,
wheel **233**, sha256 `699741dcd44d71e9b88f9ff256439bc2b8ac08e4a0fb2301f67128843e65b776`,
deploy **195** — совпадает с §A2.

**Ссылка на Гайд.** Минимальный контракт Онтологии и определение «зачётного Live Scenario» заданы
в Гайде UEPR (координаты `reference_guide` выше).

**Наблюдаемые факты.** Разрешение координат LS дало doc_id 889 (версия 2,
`LIVE_SCENARIO_H2_SHARED_v2.md`); разрешение координат Гайда — doc_id 1303.

Зачётный LS выполняется в **read-only** режиме (dev-узел заморожен); запись в базу и изменение
служб/node.json исключены. LS-документ — единственный источник гейтов; эта секция именует его
координатами и связывает с результатом.

## §END

**Финальная сводка H2_SHARED_ONTOLOGY v1.7.19:**
- h2_shared = язык (§7) с 16 R-*-CENTRAL правилами; текущая версия — 0.56.104 (§A2).
- §7.8 durable persistence + аутбокс (`PersistencePort`, миграция `0070`, 0.56.104).
- Ring 0 / Ring 3 / Ring E как абстрактная структура доступа (C-12, C-13), без имён сервисов.
- NATS/SQL/KV/MinIO/секреты/топология/оркестрация/логирование — предмет ядра.
- Оркестрационный движок `handle_orchestrated_phase()` (C-15) — единая точка dispatch.
- TOTAL-LOG (C-16/C-17/C-18/C-20) — прозрачность ядра.
- §11.7.5 лимиты 20/1800 — единственный действующий норматив.
- §7.2a «Ring 0-only модули»; §7.2 `transport.send_request`/`publish_event`,
  CLI `h2_shared.cli.probe`, `h2_shared.cli.evidence`, `h2-probe readiness`.
- §14 Generic input/result (владелец — этот документ).
- §15 Capability Manifest (final, post-G4).
- §А.1-agents.norm — норма «новые сервисы Ring 3 только по Guide».
- §A1 `implementation_contract` (11 строк); §A2 текущие факты версии; §A3 4 таблицы канона;
  §A4 инвентарь §6 = 12; §A5 `owui_functions`.
- §A6 «Зачётный Live Scenario» — LS именован координатами и связан с кандидатом
  0.56.104 / wheel 233 / deploy 195.
- 11 канонов ядра нормативно определены здесь; каноны сервисного слоя, стандартные и
  REGISTER-CONFLICT каноны — по ссылке.
- §RING3 Ring 3 инварианты AVAL (7 rule_id) + Ring 0 dynamic (5 rule_id).

Без внешних URL.

## §RING3. Ring 3 инварианты AVAL

> Владелец нормы: H2_SHARED_ONTOLOGY (этот документ) + H2_SHARED_AGENT_CODER_GUIDE приложение «Ring 3 checker reference». Scope Phase 2 (PMA_AVAL_PHASE2_DYNAMIC_RING3_v1):
> ровно 12 checker-ов — 5 `RING0_DYNAMIC` (Ring 0, в `ai_h2_shared_validation`) и
> 7 `RING3` (Ring 3, в `ai_validation`). Ring 3 инварианты — продукт уровня AVAL:
> findings persistence, terminal reconciliation, Bridge dispatch singleton, Bridge identity split, deterministic signature, OWUI guide pointer.

Ring 3 rule_id и вердикт-контракты (PASS/FAIL/BLOCKED):

- **`R3-FINDINGS-PERSISTENCE`** (`check_findings_persistence`): После MSSN в h2_findings число строк > 0 и совпадает с total_findings из reply.
  - Вердикт-контракт: PASS: persisted==total>0. FAIL: 0 findings при partial_fail/fail; persisted!=total. BLOCKED: SQL facade недоступен или mssn_id не передан.
- **`R3-TERMINAL-RECONCILIATION`** (`check_terminal_reconciliation`): В h2_request_progress ровно одна terminal-строка со счётчиками, согласованными с reply.
  - Вердикт-контракт: PASS: одна terminal-строка, counters == total, running==0, pending==0. FAIL: !=1 terminal или counters несогласованы. BLOCKED: SQL недоступен.
- **`R3-MSSN-EXEC-MODE`** (`check_mssn_exec_mode_consistency`): Согласованность exec-механизма миссии (MssnSpawner canonical, без mixed subprocess+NSSM).
  - Вердикт-контракт: PASS: canonical MssnSpawner без альтернативных прямых запусков. FAIL: mixed/альтернативный механизм. BLOCKED: source root недоступен.
- **`R3-DISPATCH-SINGLETON`** (`check_dispatch_singleton_per_node`): Ровно один активный dispatch на node_id (read-only bridge state).
  - Вердикт-контракт: PASS: нет дубликатов session_uuid среди активных workspace. FAIL: duplicate session_uuid. BLOCKED: bridge state недоступен.
- **`R3-BRIDGE-IDENTITY-SPLIT`** (`check_bridge_identity_split`): Socket-owner identity и window identity разделены (read-only, Bridge не меняется).
  - Вердикт-контракт: PASS: отдельные socket-owner и window-identity модули, без смешения. FAIL: смешение в одном модуле. BLOCKED: bridge source недоступен.
- **`R3-DETERMINISTIC-SIGNATURE`** (`check_deterministic_signature`): Один реальный MSSN acceptance и сравнение с last_signature.json соседнего прогона.
  - Вердикт-контракт: PASS: reply_status/mssn_status/total_findings совпадают с last. FAIL: расхождение. BLOCKED: last_signature.json недоступен или current не передан.
- **`R3-OWUI-GUIDE-POINTER`** (`check_owui_guide_pointer_resolution`): Активные гайды через stable pointers GUIDE_AI_VALIDATION_ACTIVE.md / ARCHITECT_GUIDE_AI_VALIDATION_ACTIVE.md по newest created_at.
  - Вердикт-контракт: PASS: оба pointer резолвятся и содержат physical guide reference. FAIL: pointer отсутствует. BLOCKED: OWUI search недоступен.

Реализация: `ring3_dynamic.py (ai_validation) — 7 Ring 3 чекеров; registry get_ring3_manifest/run_ring3; каждый результат содержит rule_id/ring/status/severity/evidence/fail_closed_reason; Bridge проверяется только read-only.`

Ring 0 dynamic rule_id (`RING0_DYNAMIC`, ai_h2_shared_validation):
`R0-DYN-LOCAL-MARIADB`, `R0-DYN-AUDIT-TABLES`, `R0-DYN-SECRETS-MASKED`,
`R0-DYN-LLM-DEEPSEEK-V4-FLASH`, `R0-DYN-EVIDENCE-PROVENANCE` — каждый результат содержит rule_id/ring/status/severity/evidence/fail_closed_reason.

**End of H2_SHARED_ONTOLOGY v1.7.19**