← к элементу · к схеме
Онтология h2_shared
| Продукт | h2_shared |
| Контур | dev |
| Тип документа | Онтология |
| Координаты чтения | {"op": "get_document", "env": "dev", "product": "h2_shared", "doc_type": "Онтология", "latest": true} |
| Версия | h2-shared-ontology-v1.7.19 |
| SHA-256 | eb20f2d2e538e5eb405e55fd9e261a74d34b6c752cb620ed3594e91aaea13376
сверено
|
| Размер | 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**