← к элементу · к схеме
Гайд Пользователя ADB
| Продукт | ai_docs_broker |
| Контур | prod |
| Тип документа | Гайд Пользователя |
| Координаты чтения | {"op": "get_document", "env": "prod", "product": "ai_docs_broker", "doc_type": "Гайд Пользователя", "latest": true} |
| Версия | 0.48 |
| SHA-256 | c504db776e2cad4bd3e69b0f2dac1d1086ecf7ac86cb606272d2c4fa37e19369
сверено
|
| Размер | 222464 байт |
Полный текст
# ai_docs_broker: Гайд Пользователя (prod) — 0.48
## §CHANGELOG 0.48
Точечная редакция по директиве Оператора (патч легаси, П6): добавлен справочный блок
«Фактическая модель платформы» — корректная модель H2 для читателей платформенных
документов (сервисный слой Ring 3, внешние оркестраторы, LEGACY reasoning-цикла).
Построено на редакции 0.47 (правило оформления документных ссылок сохранено без
изменений). Контракты API, операции, права записи, проверка SHA и продуктовые
процедуры не меняются.
## Фактическая модель платформы (справка; сверяй с документами)
Платформенные документы исторически используют термин «агент». Фактическая модель
платформы H2 по состоянию на 2026-09-25:
- **h2_shared** — ядро H2: runtime, NATS/SQL/KV, аудит, MSSN.
- **Ring 3** — сервисный слой **без LLM**: ИТ-продукты и интеграционные сервисы
(включая ai_connect_orchestrator, ACO). Контракт запуска — `run_mode=plain_run`.
- **ИИ-агенты-оркестраторы** — внешние по отношению к H2: ПерпКомп
(Perplexity Computer, мост `owui_perl_bridge`) и Roo Code (VS Code, мост
`owui_roo_bridge`). Соединены шлюзом ACO; запускают сервисы Ring 3 как тулзы.
- Reasoning-цикл ядра (`Orchestrator`) — LEGACY; сохраняется только для
спец-исполнителей (test_guide, ai_validation, ai_h2_shared_validation).
- Состав и статус продуктов/сервисов — факт реестра ADB (`list_products`,
`list_documents`), а не самоописание документа.
При расхождении текста документа с этим блоком: норма — реестр ADB и Онтология
h2_shared (dev, latest); сообщи о расхождении, не применяй устаревшую модель.
## §CHANGELOG 0.47
Точечное дополнение правила документных ссылок: назначение чтения, точные координаты и вызов OWUI-функции get_document_full. Разделены постоянная ссылка latest и адрес конкретной редакции version, координаты документа и собственный actor читающего агента. Уточнено различие полного чтения через функцию и низкоуровневого get_document. Остальной полный текст сохранён; runtime, права доступа и серверная проверка ссылок при регистрации этой редакцией не изменяются.
## §CHANGELOG 0.46
Точечная редакция: чтение документов выполняется по точным координатам.
Отменён обязательный предварительный обход реестра типов, включая cloud-клиентов
и первый запуск; согласованы повторные инструкции в описании get_document и ошибок.
При отсутствии или неоднозначности адреса требуется уточнение, не поиск вместо ссылки.
Контракты API, права записи, проверка SHA и продуктовые процедуры не меняются.
## Прямое чтение по координатам
Если документ указан полным JSON-запросом ADB, выполняй этот запрос напрямую.
Не вызывай list_doc_types или list_documents для подтверждения уже заданного адреса,
не подбирай синонимы doc_type и не меняй env/product в поисках похожего документа.
Метаданные уже полученного onboard можно использовать при совпадении координат.
Это правило действует и для первого запуска, и для облачных клиентов.
Если точных координат нет, адрес неоднозначен, документ не найден либо запрос
возвращает E_BAD_DOC_TYPE/E_DOC_TYPE_DEPRECATED, сохрани фактический ответ.
Прямо сообщи Постановщику: какой документ нужен, зачем, где в исходном документе
вместо точной ссылки требуется поиск и какие координаты отсутствуют или не работают.
Запроси точный JSON-адрес; не выбирай кандидата самостоятельно.
Доступную независимую часть чтения можно продолжить; недоступное чтение
не обозначается выполненным.
list_doc_types и list_documents сохраняются как операции API для явно поставленных
задач просмотра реестра, диагностики или исправления адресов. Их описание ниже
не является поручением выполнять такой поиск при обычном чтении документов.
Это правило имеет приоритет над прежними предписаниями искать или перебирать типы.
## §CHANGELOG 0.45
Единый журнал работы ведётся через OWUI Function в ADB. Карта документов
и краткий контекст входят в результат онбординга без повторной хронологии.
Проверка SHA, центрального журнала и фактического времени сохранена;
продуктовые разрешения и контракты runtime не меняются.
## §CHANGELOG 0.44 относительно 0.43 (2026-09-21)
Полная новая редакция по прямому поручению Оператора об очистке битых документных ссылок. Исправлены подтверждённые действующие адреса: Гайд UEPR принадлежит prod/adb_meta, а не prod/ai_docs_broker; в процедуре закрытия дополнительно исправлена среда Онтологии h2_shared на dev и шаблон пользовательского гайда на prod. Для этой редакции заменено 1 JSON-ссылок/шаблонов (1 UEPR, 0 Онтология); изменения не отменяют требований документов.
Разрешимые ссылки заменены проверенными каноническими адресами, а не удалены вместе с нужной зависимостью. Неактивная история и датированные доказательства сохранены без подмены наблюдений. Архив ADB не запрашивался и не изменялся. Исправление документации не означает внедрение нового guard, исправление runtime, повторную валидацию продукта или восстановление недоступных файлов других записей.
## §CHANGELOG 0.43 относительно 0.42 (2026-09-21)
Полная новая редакция по прямому поручению Оператора. Добавлено обязательное правило документных JSON-ссылок и порядок отказа при невозможности однозначного исправления. Разделены действующая обязанность автора и проектируемая серверная автоматизация: автоматическая проверка ссылок этим документом НЕ объявляется внедрённой. Историческое содержание сохранено; код, runtime, wheel, deploy и прежние результаты тестов не менялись.
## Строгое правило документных ссылок при публикации
Это обязательное правило подготовки нового документа или новой полной редакции любого типа и любого продукта. Оно действует для всех рабочих ссылок на документы ADB, включая ссылки в таблицах, примечаниях, приложениях и JSON-примерах, предназначенных для фактического вызова.
### Канонический адрес
Постоянная ссылка на актуальный документ оформляется полным JSON-запросом с op, env, product, doc_type и latest:true. Для ссылки на конкретный отчёт или редакцию используется точная version вместо latest, как описано ниже. Канонический пример:
```json
{"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Гайд Пользователя","latest":true}
```
Автор обязан проверить, что запрос действительно выбирает нужный актуальный документ. Для любого продукта Гайд Пользователя адресуется в prod независимо от среды исполнения продукта. Прочие типы сохраняют свою подтверждённую среду и владельца. Actor добавляется при вызове API и не является частью постоянной ссылки.
Ссылка только на Files ID, OWUI Files URL, document ID, закреплённую версию или локальное имя файла не является допустимой постоянной ссылкой. Имя продукта, тип и среда не угадываются по названию файла. Переход на документ другого продукта допустим, если это именно указанный автором целевой продукт, а не результат ошибочной подстановки.
### Как оформить и открыть ссылку внутри документа
Рабочая ссылка состоит из назначения документа и точных координат ADB. Перед JSON напиши, зачем и когда его читать, и укажи OWUI-функцию `get_document_full`. Это инструкция для вызова функции, а не обычная кликабельная веб-ссылка.
Пример оформления:
#### Гайд пользователя моста Roo
Прочитай перед постановкой задач ИИ-Кодеру Roo, чтобы правильно отправлять задания и получать результаты.
Получить полный текст через OWUI-функцию `get_document_full`:
```json
{"op":"get_document","env":"prod","product":"owui_roo_bridge","doc_type":"Гайд Пользователя","latest":true}
```
Правила для автора:
- `doc_type` указывай точно как в ADB, с исходными пробелами и регистром. До публикации проверь, что запрос возвращает именно нужный документ.
- `env` и `product` обозначают место хранения целевого документа. Фиксированные координаты общих документов H2, ADB и моста не заменяй продуктом или средой получателя.
- Для актуального гайда оставляй `latest:true`: при обновлении документа ссылка не меняется. Найденные версию, ID, Files ID и SHA сохраняй как реквизиты проверки, не как постоянный адрес.
- Для конкретного отчёта, аудита или явно заданной редакции передавай точную `version` вместо `latest`. Это адрес определённой редакции, а не ссылка на постоянно актуальный гайд. Не используй случайную версию для обхода неоднозначности серии.
- Если для идентичности документа нужен `node`, сохраняй подтверждённый узел в координатах. Не выдумывай поля API и не отбрасывай нужные ограничения.
- В универсальном шаблоне явно обозначай параметры своего продукта, которые нужно подставить из поручения. В готовой ссылке конкретного продукта должны быть заполненные значения; общие платформенные ссылки остаются фиксированными.
- `actor`, секреты авторизации, `request_id` и время вызова в постоянную ссылку не включай.
Правила для читающего агента:
1. Передай JSON-координаты в OWUI-функцию `get_document_full`. Имя функции — `get_document_full`, но операция внутри JSON остаётся `"op":"get_document"`.
2. Добавь `format:"json"` и собственный `actor`: продукт и узел своей роли, тип, UUID и полный URL своей сессии. Не подставляй владельца документа вместо себя. После чтения проверенного UEPR добавляй `actor.product_version` из его тела; до bootstrap-чтения UEPR версию не угадывай.
3. Для `get_document_full` не передавай `request_id` и `emitted_at`: функция создаёт их сама. Это правило относится к этой функции и не отменяет actor-контракт прямых операций ADB.
4. Выполни авторизованный `POST https://chat.h2platform.ru/api/chat/completions` с оболочкой ниже. `content` содержит сериализованную строку JSON из координат, `format` и `actor`, а не объект и не буквальный текст заполнителя.
```json
{"model":"get_document_full","stream":false,"messages":[{"role":"user","content":"<сериализованный JSON: координаты документа, format и собственный actor>"}]}
```
5. Проверь HTTP-успех, `status:"ok"`, `integrity_verified:true`, соответствие `ref` запрошенному документу и наличие полного `text`. Ответ при `format:"json"` — непосредственно JSON, не `choices` и не вложенный SSE. Функция получает файл и проверяет SHA-256 и размер, если он указан; повторно скачивать тот же файл только ради чтения не требуется.
6. Сохрани ответ и прочитай требуемый текст. Успешный вызов подтверждает получение и целостность документа, но не его прочтение. Если показ в инструменте усечён, дочитай сохранённый текст частями.
7. Если ссылка не разрешилась, сохрани фактическую ошибку и запроси точные координаты по разделу «Прямое чтение по координатам». Не запускай поиск и не подбирай другой документ.
Функция `get_document_full` служит только для чтения документов. `onboard`, регистрация и другие операции выполняются через существующий интерфейс ADB; переносить их в `get_document_full` нельзя. Правило не предоставляет новых прав доступа и не объявляет автоматическую проверку всех ссылок при регистрации внедрённой.
### Исправление или отказ
Если обнаружена рабочая ссылка на Files ID или document ID, до публикации требуется найти подтверждённые координаты целевого документа среди актуальных записей ADB, заменить ссылку на JSON и проверить результат запроса. Замена допустима только при однозначной идентичности документа; несколько записей разных версий сами по себе не означают несколько разных документов.
Если цель отсутствует, неоднозначна, недоступна для необходимой проверки, не совпадает с указанным продуктом/типом или latest выбирает другую серию, публикация запрещена. Автор должен вернуть явную ошибку со ссылкой, её местом в тексте и причиной; нельзя оставлять исходный ID, выбирать случайного кандидата или регистрировать частично исправленный текст. Архивные записи для такого восстановления не используются.
Если для выбора нужны node, серия или диапазон применимости, их нельзя молча отбросить ради пяти полей. Если утверждённый канонический запрос не сохраняет эту идентичность, это неоднозначность и основание для отказа; отсутствующие параметры API не выдумываются. Обход через закрепление случайной версии запрещён.
### Что не подменяется JSON-ссылкой
Датированные ID, версии, SHA, parent_doc_id и Files ID как доказательства конкретной операции не являются постоянными адресами. Они сохраняются как evidence, явно отделённое от действующих инструкций; историческая копия внутри полного документа не переписывается задним числом. Если рядом требуется рабочий переход на документ, дополнительно указывается каноническая JSON-ссылка.
Внешние веб-источники, ссылки на сессии, исходники, тестовые артефакты и технические шаблоны Files API не превращаются в ссылки ADB. Само скачивание файла по Files API после get_document остаётся штатным транспортом. Произвольная пометка «история» или размещение адреса в блоке кода не разрешает скрывать рабочую неканоническую ссылку.
### Целостность исправленного документа
Проверяется полный текст фактически публикуемого файла, а не только начало и не отдельно переданный inline content. После исправления ссылок создаётся новый файл; SHA-256 и размер считаются по его двоичным байтам. Исходный файл и исторические доказательства не перезаписываются. Новая редакция содержит честный CHANGELOG, а после регистрации обязательны get_document/latest и повторное скачивание с проверкой байт.
### Статус автоматизации на дату редакции
Обязательное правило выше действует для автора и ИИ-Арха уже сейчас. Серверный контроль ссылок с автоматическим преобразованием Files ID и отказом при неразрешимой ссылке находится на стадии концепта и НЕ внедрён этой публикацией; нельзя обещать, что действующий register_document уже обеспечивает это поведение.
В исследованном пакете 0.9.0a33 существующий SMART-INTAKE проверяет эволюцию/CHANGELOG через LLM, не заменяя проверку документных ссылок. Для нового контроля требуется независимая детерминированная проверка полного файла перед регистрацией. При невозможности проверить или исправить ссылку автор обязан остановить публикацию сам, не полагаясь на текущую серверную реализацию.
## §CHANGELOG 0.42 относительно 0.41.dev3 (2026-09-21)
Полная новая редакция по решению Оператора: исправлены действующие ссылки и правила размещения Гайда Пользователя. Для любого продукта этот тип хранится только в prod, независимо от dev-only/dev-and-prod runtime. Постоянная ссылка содержит ровно op, env, product, doc_type и latest:true, без версии, ID и Files URL:
```json
{"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Гайд Пользователя","latest":true}
```
Поле actor добавляется вызывающей стороной по контракту ADB; это не часть постоянных координат документа. После lookup проверяются возвращённые метаданные и двоичный SHA-256.
Коррекция относится только к документации: runtime, wheel, deploy, сценарии и прежние результаты проверок не менялись и заново не аттестованы. Датированные снимки, ID/версии/SHA в доказательствах и исторические приложения не являются текущими ссылками; они сохраняются как свидетельства своего времени. Прежние требования искать или публиковать пользовательский гайд в dev больше не действуют. Описания старых guard a26/a30 не доказывают сегодняшнюю реализацию; наличие нормативного правила не объявляется успешным runtime-тестом.
> **Заголовок: документ prod, runtime dev / heavy02.** Продуктовый гайд пользователя
> для РАЗРАБОТКИ ai_docs_broker. Настоящий заголовок **ЗАМЕНЯЕТ (supersede)**
> исторические инструкции из скопированного ниже тела, если они предписывают
> устанавливать wheel `0.9.0a30` без отдельной проверки runtime. Полный гайд
> хранится только в prod; прежнее исключение для dev-гайда отменено решением Оператора.
> - product: `ai_docs_broker`; среда документа: `prod`; runtime: `dev`; узел: `heavy02`.
> - Исторический снимок runtime из заголовка предшественника, не новая аттестация: **0.9.0a32** (wheel_id 127, release_id
> `bc5d3f6e-8bc0-4a86-8165-60105a78c2e9`; corrective successor к 0.9.0a31 — actor-reinjection fix для
> `who_am_i` на полном публичном `handler.handle()`).
> - Принятый (accepted) dev deploy на момент публикации: deploy 96 → wheel 109 =
> `0.9.0a26`; продвижение deploy/product_state выполняется только после
> прохождения LS v0.19 и независимой валидации (Гайд ЖЦ ИТ-продукта H2 v0.6).
> - **Как получить этот документ (реальные команды):**
> ```json
> {"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Гайд Пользователя","latest":true}
> ```
> Гайд ИНСТРУМЕНТА независимой валидации (ai_validation) в реестре prod:
> ```json
> {"op":"get_document","env":"prod","product":"ai_validation","doc_type":"Гайд Пользователя","latest":true}
> ```
> - Историческая линия: prod-version полного платформенного гайда — **0.41**
> (doc_id 632, файл `ADB_User_Guide_v0.41.md`, sha256
> `8d8685599743354056dd3391f061bc3c3a939674ab9fef93e5bb3b2725d99555`).
> Тело ниже скопировано из этого prod-гайда **с сохранением содержания**
> (после нормализации переводов строк LF/CRLF; это НЕ побайтовая
> идентичность оригинальному файлу), с добавлением только настоящего
> заголовка; историческое приложение и CHANGELOG сохранены.
> - Runtime продукта dev-only: продвижение runtime в prod, широкие merge и прочие env не
> выполняются в рамках этой задачи.
## Полный канонический текст (содержание из prod-гайда 0.41, newline-normalized)
# ai_docs_broker: Гайд Пользователя 0.41
## §CHANGELOG 0.41.dev3 (правки G1–G4)
Версия `0.41.dev3` — кумулятивная редакция Гайда Пользователя ADB для контура dev.
Прежние разделы и исторические §CHANGELOG сохранены. Wheel, deploy, runtime, service и
migrations этой задачей НЕ меняются; Guide-Runtime Parity сверена с runtime a33-dev9
(wheel 150 sha `f667bce4…0b8f2`, deploy 123).
- **G1 (§5.6).** Добавлен контракт discovery: публичного `list_ops` нет, список действующих
операций получается стандартным механизмом ошибки (`E_UNKNOWN_OP` → `errors[0].data.known_ops`).
- **G2 (§1.5, §2.1–§2.3, §3.1–§3.4, §5.6).** Под каждый WRITE-op добавлен блок
«Обязательные поля», снятый эмпирически из `errors[0].data.missing_fields`; в §5.6 описано
правило `E_MISSING_FIELD`.
- **G3 (§1.3, §5.6).** Добавлен реестр `doc_type`: операция `list_doc_types`, регистро- и
пробело-чувствительность, поведение при `E_BAD_DOC_TYPE` (поле `data.allowed` на текущем
runtime отсутствует).
- **G4 (§5.1).** Усилен actor-контракт для `__unknown__`-клиентов и порядок получения
`product_version` из SHA-проверенного тела UEPR.
Эмпирическая база правок (ответы брокера a33): `E_UNKNOWN_OP.data.known_ops` = 59 операций;
`list_doc_types(env=dev, product=ai_docs_broker)` = 52 типа; `register_document` без полей →
`E_MISSING_FIELD` с `data.missing_fields = [product, doc_type, version, owui_file_id, filename, sha256]`;
`get_document(doc_type=___nonexistent___)` → `E_BAD_DOC_TYPE` без поля `data.allowed`.
## §CHANGELOG 0.41
Полная редакция. Синхронизация с executor-v0.41: канонические координаты
и owui_file_id без искажения, проверяемая карта и итоговый контекст,
SHA тела Гайда вместо доверия guide_hint, фактический хронометраж,
сводка bootstrap и полный учёт ошибок/пробелов. Права не расширены.
## §CHANGELOG 0.40
Полная накопительная редакция. Журнал и документные ссылки синхронизированы
с Онбордингом executor-v0.40: обнаружение всего актуального комплекта,
выборочное чтение для понимания сути и состояния, подробности по задаче.
Обязательное чтение всех тел и запрет отложенного чтения исключены;
контракты, разрешения, SHA скачанных тел и журнал сохранены.
Понимание карты проверяется в задании прямым открытием нужного документа,
не дополнительным онбордингом. Исторические приложения не изменены.
## §CHANGELOG 0.39
Синхронизирован порядок журнала с Онбордингом executor-v0.39: bootstrap,
затем start_session до onboard; UTC с миллисекундами; полный readback и корректный
финал ready/blocked. Продуктовые разрешения и runtime-контракты не расширены.
## §CHANGELOG 0.38
Полная редакция после независимого холодного старта. Учтён фактический дрейф ЖЦ к v0.5, исправлен порядок wheel_id до установки/LS; живые разрешения не расширены. Исторические приложения сохранены побайтно.
## Сверка изменившегося ЖЦ перед итогом
19.09.2026 в 09:08:18Z получен и прочитан изменившийся норматив:
`{"op":"get_document","env":"prod","product":"adb_meta","doc_type":"Гайд ЖЦ ИТ-продукта H2","latest":true}`.
Evidence этого чтения: version v0.5, SHA
`8dfe5c49ad14836c02f27fa6f46cd9f7d42e5ae49d87970eb9c29dafe4201c9f`,
17497 байт; зарегистрирован владельцем нормы 09:00:00.620Z.
Изменены шаги 5/9/13: первичная регистрация артефакта выполняется до установки
и зачётного Live Scenario; после LS и ai_validation завершается учёт release.
Прежнее противоречие порядка wheel_id больше не является нормативным блокером.
Оно не заменено фиктивным успехом: эта сессия не регистрировала wheel/deploy/run
и не устанавливала a30. TD-2026-09-19-04 остаётся OPEN по фактической цепочке.
Остальные нормы, в том числе конфликт dev/prod Гайда Пользователя, не изменены.
Прежние ссылки на v0.4 внутри датированных наблюдений и истории описывают прошлое,
а не текущую инструкцию.
## Статус публикации
Редакция `0.41` одобрена Оператором 19.09.2026 для регистрации и двух чистых онбордингов. Это полный документ. Регистрация подтверждается ответом ADB и контрольным скачиванием с проверкой SHA/размера. Понимание выбора документа проверяется в задании. Установка a30, изменение runtime, секретов/данных, регистрация wheel/deploy/прогонов не разрешены; приёмка продукта BLOCKED.
Исторический родитель: version `0.36`, SHA `fe61194a95198fa7ed1a6b6f643647c2994ec28a1265675f8a0ea4423aeacdd1`. Координаты latest ниже предназначены для текущей редакции, а не поиска родителя.
## §CHANGELOG 0.37
Документные ссылки заменены ADB-координатами; установка и откат a30 включены в существующий гайд. Размещение остаётся prod по решению Оператора, нормативный конфликт не скрыт.
## Координаты документов в ADB
Любое упоминание документа ниже разрешается через эту таблицу, а не через имя локального файла, старый ID или прямой Files URL. Запросы показывают business payload; полный actor добавляется по действующему гайду. Найденные координаты и метаданные сохранить. Когда тело нужно по задаче, сверить env/product/type и узел по UEPR, скачать по возвращённому owui_file_id, проверить SHA и размер, прочитать нужные разделы. Сам Files download является транспортом после поиска в ADB, а не постоянной документной ссылкой; найденный документ не обязательно сразу скачивать.
| Документ | Координаты поиска |
|---|---|
| ai_docs_broker: Гайд Пользователя | `{"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Гайд Пользователя","latest":true}` |
| ai_docs_broker: Онтология | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"Онтология","latest":true}` |
| ai_docs_broker: Гайд Архитектора | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"Гайд Архитектора","latest":true}` |
| ai_docs_broker: Концепт Развития | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"Концепт Развития","latest":true}` |
| ai_docs_broker: Live Scenario | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"Live Scenario","latest":true}` |
| ai_docs_broker: Отчёт Валидации | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"Отчёт Валидации","latest":true}` |
| ai_docs_broker: Аудит UEPR | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"Аудит UEPR","latest":true,"node":"heavy02"}` |
| ai_docs_broker: UEPR | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"UEPR","latest":true,"node":"heavy02"}` |
| adb_meta: Закрытие сессии ИИ-Арх | `{"op":"get_document","env":"prod","product":"adb_meta","doc_type":"Закрытие сессии ИИ-Арх","latest":true}` |
| ai_docs_broker: Стандарт (Техдолг) | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"Стандарт","version":"tech-debt-log-v48.3"}` |
| ai_docs_broker: Дорожная Карта | `{"op":"get_document","env":"dev","product":"ai_docs_broker","doc_type":"Дорожная Карта","latest":true}` |
| ai_docs_broker: Онбординг | `{"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Онбординг","latest":true}` |
| adb_meta: Гайд UEPR | `{"op":"get_document","env":"prod","product":"adb_meta","doc_type":"Гайд UEPR","latest":true}` |
| ai_docs_broker: Гайд Аудита | `{"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Гайд Аудита","latest":true}` |
| adb_meta: Гайд ЖЦ ИТ-продукта H2 | `{"op":"get_document","env":"prod","product":"adb_meta","doc_type":"Гайд ЖЦ ИТ-продукта H2","latest":true}` |
| adb_meta: Письмо-открытка ии-арх ПерпКомп для онбординга | `{"op":"get_document","env":"prod","product":"adb_meta","doc_type":"Письмо-открытка ии-арх ПерпКомп для онбординга","latest":true}` |
| ai_validation: Гайд Пользователя | `{"op":"get_document","env":"prod","product":"ai_validation","doc_type":"Гайд Пользователя","latest":true}` |
Техдолг: указан точный адрес согласованной серии tech-debt-log-v48.3 этого комплекта; актуальность подтверждается ADB, не именем файла. Для нового current сначала выполнить `{"op":"list_documents","env":"dev","product":"ai_docs_broker","doc_type":"Стандарт","limit":100,"offset":0}`, прочитать все страницы, выбрать именно серию tech-debt-log и затем запросить её точную version. Не подменять её contour-binding и не выбирать по максимальному id. При неоднозначности отметить GAP; не придумывать параметр series или version_prefix.
Версии и SHA в старых измерениях являются provenance этого измерения. Ни координаты latest, ни текст новой редакции не делают старые измерения свежими. Ссылки на сессии, API endpoint-шаблоны, пути исходников и имена первичных JSON/test evidence не являются ссылками на документы ADB. Их доступность проверяется отдельно; локальный путь не считается доказательством доставки новому исполнителю.
Полный LS и встроенная инструкция установки входят в тела соответствующих документов. Перед использованием подтвердить эту версию через ADB и проверить SHA; никаких отдельных локальных .md для продолжения не требуется.
## §CHANGELOG v0.36 относительно prod v0.35
По прямому решению Оператора 19.09.2026 полный продуктовый черновик, ранее предназначенный для dev, публикуется в prod/ai_docs_broker/«Гайд Пользователя». Он заменяет prod v0.35 (id632), а не создаёт вторую конкурирующую серию. Отдельная dev-регистрация для этой публикации больше не требуется. Перенесён уточнённый CHANGELOG LC04; полный каталог операций и история сохранены. Среда хранения документа prod не меняет фактическую среду runtime dev/heavy02. Прежний отказ E_NORM_WRONG_ENV остаётся фактом работы a26, но не блокирует разрешённую prod-публикацию. Узкий dev-guard описывает только офлайн-кандидат a30; установка и исправление runtime этой регистрацией не выполняются. Родитель этой публикации: prod v0.35; указания v0.34 ниже сохраняют происхождение содержания.
## Рамки этой редакции
Полная редакция принята Оператором для публикации 19.09.2026. Дата среза: 19.09.2026; свежесть отдельных
наблюдений указана в evidence, а не заменена датой сборки документа.
Действующий runtime: a26, dev / heavy02, deploy96 / wheel109.
Кандидат a30 имеет отдельную офлайн-приёмку и НЕ установлен.
Отсутствие prod deploy при dev_only является N/A, а не аварией.
UEPR для heavy02 зарегистрирован в dev и описывает a26; текущую редакцию получать по координатам таблицы. Приёмка остаётся BLOCKED.
Разрешены чтение, безопасная диагностика, файлы, OWUI Files и agent_work_log. Оператор отдельно разрешил публикацию документов этого комплекта.
Запрещены без отдельного разрешения установка, restart/stop, миграции, изменение
кода или конфигурации узла, регистрация wheel/deploy/прогонов,
deprecate/retire/cleanup и удаление данных. Тест с env=dev не становится безопасным
сам по себе. Примеры WRITE ниже являются описанием, не командой к исполнению.
Фрагменты запросов сокращены: к каждому добавляется actor по полному контракту.
Текущие нормативы получают по (env,product,doc_type,latest=true), SHA проверяют
при скачивании. ID/версии/SHA родителей ниже нужны для provenance, не для вечного
выбора current. Приложенная история никогда не является действующей инструкцией.
Родитель: id=632; версия=0.34; SHA-256 `074a017b8aba1017a11329daff1152b724103a30d957110bbb925f49907f5a28`.
## Изменения этой полной редакции
Полная редакция каталога пользовательских операций. Исправлены actor/bootstrap, источник версии, onboard и products_state; runtime и журнал вынесены в действующую часть. Кандидатный guard не приписывается работающему a26; исходная история сохранена точно.
**Дата:** 2026-09-18
**Продукт:** ai_docs_broker
**Фактический runtime:** a26 / dev / heavy02. a30 только кандидат.
**Родитель:** v0.34 (doc_id=632)
**Кумулятивно к:** v0.7 → v0.22 → v0.26..v0.29 → v0.30..v0.33 (весь op-каталог собран заново, не delta).
**Предыдущая редакция (v0.35 LC04, офлайн-кандидат a30, не установленный a26):** заменены активные секции §1.8, §4.3, §5.1, §5.7, §R-RUNTIME.5 (не delta-префикс): продуктовый dev-Гайд Пользователя разрешён узкой координатной проверкой (216-кейсная матрица), `actor.product_version` берётся только из тела UEPR (`uepr.product_version`), §R-RUNTIME.5 — неразрушающий install (без `rm -rf .venv`).
**Историческое (v0.34, более не активно):** новый раздел §5.7 «Платформенные нормативы и тип `Гайд Пользователя`» — перечень типов-нормативов платформы, их владелец, требование по среде, код `E_NORM_WRONG_ENV` и условия его появления; отдельно описано, что документ продукта того же типа проверкой норматива не затрагивается. Также зафиксировано, что строка документа в `get_document`/`list_documents` несёт `created_at`/`updated_at`/`added_by`. Основание: CR-ADB-2026-09-18-NORM (дефект Б-13, регрессия платформы).
**Что было в v0.33:** §3.2 `deprecate_document` — `deprecated_by` убрано из обязательных полей.
---
## §1. Простой минимум — 9 операций для 90% работы
Если вы никогда не работали с ADB, начните только с этих 9. Все остальные разделы читайте, когда понадобится.
### 1.1 `health` — проверить, что сервис жив
**Зачем:** первый вызов при подозрении что что-то не так.
**Ключевые поля запроса:** `env` (`prod` или `dev`).
**Ключевые поля ответа:**
- `status='ok'` — сервис отвечает.
- `broker_version` — версия wheel (например, `0.9.0a12`).
- `uptime_s` — сколько работает.
**Пример:**
```json
{"op":"health","env":"prod"}
```
### 1.2 `onboard` — получить пакет документов продукта одним вызовом
**Зачем:** собрать продуктовый пакет после bootstrap и обязательного журналирования. Это не замена чтения Онбординга и не доказательство полноты нормативов.
**Ключевые поля запроса:**
- `env` — `prod` или `dev`.
- `product` — имя продукта (например, `ai_docs_broker`).
- `node` — узел (например, `heavy02`), опционально.
- `include_texts=true` — вернуть тексты документов в ответе (без этого только метаданные).
**Ключевые поля ответа:**
- `ready` (`true`/`false`) — удалось ли собрать пакет.
- `docs.<doc_type>` — актуальный документ по каждому типу.
- `adb_self.user_guide` — этот гайд.
- `transports.*.user_guide` — гайды транспортов, которые продукт использует.
- `onboarding_ref` — ссылка на актуальный Онбординг Исполнителя.
**Что делать, если `ready=false`:** пакет неполный. Смотреть `reasons` в ответе и добирать точечно через `get_document`.
**Пример:**
```json
{"op":"onboard","env":"prod","product":"ai_docs_broker","include_texts":true}
```
### 1.3 `get_document` — прочитать документ
Для чтения полного текста по ссылке внутри документа используй OWUI-функцию `get_document_full` по разделу «Как оформить и открыть ссылку внутри документа». Следующий абзац описывает низкоуровневый ответ прямой операции ADB; в `get_document_full` скачивание и проверка файла уже выполнены функцией.
Выбор current: `env/product/doc_type/latest=true`; exact active: `version`; явная
строка: `doc_id`; подбор по диапазону: `for_product_version`. Ответ находится в
`data.row`. Не рассчитывайте на `text`: скачайте `row.owui_file_id` через Files
API и проверьте SHA по `row.sha256`. Архив читается отдельной операцией.
Исторические ID не подставляются в latest.
**Реестр `doc_type` (G3).** `doc_type` регистро- и пробело-чувствителен; реестр типов
env-scoped. Получить актуальный список:
`{"op":"list_doc_types","env":"<env>","product":"<product>"}` (ответ `data.doc_types[]`).
При заданных координатах выполняй `get_document` напрямую, без предварительного
`list_doc_types`, в том числе при первом запуске и из облака.
При `E_BAD_DOC_TYPE` сохрани ответ и запроси у Постановщика точные координаты
по разделу «Прямое чтение по координатам»; автоматически искать другой тип нельзя.
### 1.4 `list_documents` — список актуальных документов
`env` обязателен; `product/doc_type/version/limit/offset` опциональны.
Ответ: `data.documents` и совместимый алиас `data.rows`;
`data.count` и алиас `data.total` — число до пагинации.
`data.pagination` содержит limit/offset. Обходите страницы до `count`.
### 1.5 `register_document` — регистрация, WRITE
Обязательны `env/product/doc_type/version/owui_file_id/filename/sha256` и actor.
`size` опционален, но для публикации передаётся измеренный размер. `uploaded_by`
вычисляется из actor; значение в body игнорируется. `parent_doc_id` опционален;
поля `parent_id` нет. Файл сначала загружается в OWUI Files, затем брокер сам
проверяет скачанные байты/SHA. Перезапись только с `allow_overwrite=true`.
Регистрация разрешена только для согласованного комплекта документов; прочие WRITE требуют отдельного разрешения.
**Обязательные поля (G2, эмпирически a33):** `env, product, doc_type, version, owui_file_id, filename, sha256`.
### 1.6 `list_products` — реестр продуктов
`env` обязателен, `product_type/parent` опциональны. Ответ:
`data.products`, `data.counts`.
### 1.7 `list_wheels` — список wheel
Фильтры `env/product/limit`. Ответ: `data.wheels`, `data.counts.wheels`.
Канонические поля включают `filename/owui_file_id/sha256/size/version`;
`wheel_url` не является текущим полем записи.
### 1.8 `list_deploys` — список деплоев
Фильтры `env/product/node/status/limit`. Ответ `data.deploys` содержит
`deploy_id/wheel_id/wheel_version/wheel_sha256/deployed_at/status`.
Это не тонкая проекция.
### 1.9 `list_nodes` — список узлов
Фильтры `class/status/include_archives/include_test/include_retired`; по
умолчанию test и retired исключены. Ответ `data.nodes`, `data.counts`,
опционально `data.nodes_archive`. Реестр узлов не разделён собственной
env-колонкой.
## §2. Жизненный цикл сборки — 5 операций
Когда вы выкатываете новую версию продукта.
### 2.1 `register_product` — регистрация продукта, WRITE
Обязательны `env/product`; опциональны
`product_type/parent/display_name/description`. Не используйте вымышленные
обязательные `runtime/kind`. Ответ `data.product_id/created/updated/row`.
**Обязательные поля (G2, эмпирически a33):** `env, product`.
### 2.2 `register_wheel` — регистрация wheel, WRITE
Обязательны `env/product/wheel_version/sha256/size/filename`; опциональны
`applies_to_version_range/owui_file_id/registered_by/comment`. Legacy `version`
принимается с предупреждением, но новый запрос использует `wheel_version`.
`wheel_url` не заменяет `filename/owui_file_id`. Ответ `data.wheel_id`,
`created/duplicate/row`. Регистрация не устанавливает wheel. Для a30
`wheel_id=null`; 109 относится только к a26. По действующему ЖЦ артефакт регистрируется до установки и LS, после отдельного разрешения; чужой ID не подставляется.
**Обязательные поля (G2, эмпирически a33):** `env, product, wheel_version, sha256, size, filename`.
### 2.3 `register_deploy` — регистрация деплоя, WRITE
`env/product/node/wheel_id`, опционально `deployed_by/comment`. Произвольный
`status` не передаётся: новая запись active, прежние active становятся
superseded. Ответ `data.deploy_id/superseded_ids/row`. Операция не выполняет
физическую установку и не заменяет runtime proof.
**Обязательные поля (G2, эмпирически a33):** `env, product, node, wheel_id`.
### 2.4 `get_wheel` — чтение wheel
`env/product` плюс `wheel_id` или `wheel_version`. Ответ `data.row`; отсутствие
даёт `E_NOT_FOUND`.
```json
{
"op": "get_wheel",
"env": "dev",
"product": "ai_docs_broker",
"wheel_id": 109
}
```
### 2.5 `get_product` — чтение продукта
`env/product`; ответ содержит row и subproducts, отсутствие даёт `E_NOT_FOUND`.
## §3. Работа с уже загруженными документами — 4 операции
### 3.1 `update_document` — метаданные документа, WRITE
`env/doc_id` и непустое изменение. Изменяемые метаданные:
`comment/applies_to_version_range/review_status/retired_reason`;
`parent_doc_id` валидируется отдельно. Версия/SHA/файл неизменяемы.
Пустое изменение: `E_NO_CHANGES`; запрет: `E_FIELD_NOT_EDITABLE`.
**Обязательные поля (G2, эмпирически a33):** `env, doc_id` + непустое изменение метаданных.
### 3.2 `deprecate_document` — вывод документа, WRITE
`env/product/doc_id/retired_reason` и actor; причина минимум 3 символа.
`deprecated_by` не обязателен. Действие архивирует и исключает активную строку.
Старый TD про потерю причины имеет `VERIFY_REQUIRED`, а не доказанный current:
в source есть запись retired_reason, live WRITE без разрешения не повторялся.
**Обязательные поля (G2, эмпирически a33):** `env, product, doc_id, retired_reason`.
### 3.3 `bulk_deprecate_documents` — массовый вывод, WRITE
`env/filter/comment`; `dry_run` по умолчанию true. `filter` содержит
`products[]/product_pattern/sha256_in[]`, опционально `older_than`; это не
`doc_ids`. Preview возвращает count/sample, исполнение архивирует и удаляет
active. В этой задаче запрещено.
**Обязательные поля (G2, эмпирически a33):** `env, filter, comment`.
### 3.4 `promote_document` — перенос между средами, WRITE
Канонические поля: `from_env/to_env/doc_id`; опционально
`allow_overwrite/comment/override_description/override_doc_type`.
`source_env/source_doc_id` не являются текущими полями запроса. Операция пишет
в целевой контур и требует отдельного разрешения.
**Обязательные поля (G2, эмпирически a33):** `env, from_env, to_env, doc_id`.
## §4. Точечное чтение — 3 операции
### 4.1 `get_active_deploy` — активный деплой
`env/product/node`. Ответ `data.deploy` и `data.wheel`, либо deploy=null.
ID находится в `deploy.deploy_id`, SHA/version в объекте wheel.
### 4.2 `get_document_for_node` — документ для версии узла
`env/node_id/doc_type`, опционально `product` (default ai_docs_broker).
Ответ `data.document/node/match`. Поле запроса именно `node_id`, не `node`.
### 4.3 `list_products_state` — состояние одного продукта на узле
Требует `product/node`; `env` опционально сужает контур. Это single-entity read:
ответ `data.present/env_filter/row`, промах `E_NOT_FOUND`, не список `rows`.
## §5. Стандарты и правила
### 5.1 Контракт actor
Ниже приведён контракт прямых операций ADB. При чтении через OWUI-функцию `get_document_full` собственную идентичность передаёт агент, а `request_id` и `emitted_at` создаёт функция; постоянная JSON-ссылка не содержит actor. См. раздел «Как оформить и открыть ссылку внутри документа».
Actor передаётся JSON-объектом во всех операциях, включая READ и get_document.
Поля: product, node, product_version, session_type, session_id, request_id, emitted_at, source_url.
Только bootstrap get_document допускает отсутствие product_version, но не всего actor.
Версия actor берётся из SHA-проверенного тела UEPR по порядку действующего Онбординга,
а не из metadata.version документа, health или предположения о кандидате.
Если канонический UEPR ещё описывает a25, это отдельно объявленное расхождение с runtime a26.
Для service, roo, owui и perplexity source_url обязателен и содержит действительный
полный URL сессии-инициатора. session_id является каноническим UUID текущего
исполнителя; request_id новый на каждый вызов; emitted_at имеет UTC ISO-8601 milliseconds Z.
Идентичность роли задаётся (product,node). Principal не передаётся, legacy principal
игнорируется; uploaded_by/deprecated_by формируются как product@node.
HMAC снят; hmac_phase и caller_kind не являются обязательными клиентскими полями.
Это контракт идентичности, а не разрешение изменять данные или обходить права операций.
**G4 — `__unknown__`-клиенты и порядок получения версии.** Клиенты, получившие
`E_ACTOR_MISSING_VERSION` или `E_ACTOR_REQUIRED`, обязаны выполнить Онбординг:
`{"op":"onboard","product":"<product>","node":"<node>","env":"<env>"}` получает пакет
документов включая UEPR. `actor.product_version` берётся из SHA-проверенного тела UEPR и
**не выводится** из header, каталога установки, сервисной metadata или подстановки
`product_version_source=active_deploy`. Bootstrap `get_document` для UEPR разрешён без
`product_version`, но требует остальные поля actor. Клиент, идентифицирующий себя как
`product=__unknown__` и `node=__unknown__`, гарантированно получает
`E_ACTOR_MISSING_VERSION` или `E_ACTOR_REQUIRED` и должен исправить конфигурацию до
следующего вызова.
### 5.2 HMAC-подпись
**HMAC полностью удалён из ADB в 0.9.0a9** (миграция 033). Клиент **не подписывает** запросы. Не добавляйте HMAC и legacy principal в клиентский actor.
### 5.3 Версии
Версия пакета и actor.product_version отличаются от metadata.version документа.
Применяется PEP-440, например 0.9.0a26; get_document bootstrap может не передавать
только product_version. Проверка диапазонов относится к TD-2026-09-16-04 и не
объявляется исправленной по старому плану «a13». Конкретный диапазон проверяют
по текущему контракту и безопасным тестам; WRITE ради проверки не выполняют.
### 5.4 Имена продуктов
Только lower_snake_case: `^[a-z][a-z0-9_]*$`. Валидация на входе `register_product` / `register_document` / `bulk_deprecate_documents`.
### 5.5 Кумулятивные документы (правило содержания и текущий механизм)
Гайд Пользователя, Гайд Архитектора, Дорожная Карта, Онтология, Концепт
Развития, Стандарт, Live Scenario и Онбординг публикуются полными текстами,
не delta. Это нормативное требование к артефакту.
Не путайте норму с текущим кодом: в frozen a30 механические cumulative/trivial
guards удалены; register_document оставляет PEP-440 и content-aware LLM-вызов.
Поэтому нельзя обещать конкретный `E_DELTA_NOT_CUMULATIVE` или проверку первых
30 строк как гарантированный текущий результат. Фактический валидатор,
CHANGELOG-правило и поведение некомулятивных отчётов остаются VERIFY_REQUIRED
в TDL. До закрытия долга Архитектор сам проверяет, что является полным
текстом и содержит честный CHANGELOG.
### 5.6 Ошибки — общий формат
Всегда читать фактические `status/error/error_code/errors/data` ответа. Не
строить логику на старом списке имён ошибок. Для одиночного промаха ожидается
`E_NOT_FOUND`; обязательные поля обычно дают `E_MISSING_FIELD`; неверное имя
продукта — `E_INVALID_PRODUCT_NAME`; конфликт upsert без разрешения —
`E_UPSERT_CONFLICT`; неизвестная операция — `E_UNKNOWN_OP`. Реестр типов
env-scoped; точный код неизвестного/deprecated типа проверяется на текущем
runtime. Механический `E_DELTA_NOT_CUMULATIVE` не объявляется гарантированным:
см. §5.5 и TDL VERIFY_REQUIRED.
**Discovery операций (G1).** Публичного `list_ops` нет. Список действующих операций
получается стандартным механизмом ошибки: любой неизвестный `op` даёт ответ
`status=error`, `error_code=E_UNKNOWN_OP`, `errors[0].data.known_ops = [...]` (на
runtime a33-пары список содержит 59 имён). Пример проверочного запроса:
`{"op":"__discover__"}`. Имена операций `snake_case` и регистр-чувствительны.
`ping`, `help`, `capabilities`, `describe`, `version`, `operations`, `list_operations`,
`upload_file`, `put_document`, `upload_document` **не являются** операциями брокера.
Не строить клиентскую логику на fingerprinting произвольными именами: одного вызова с
известным неверным op достаточно для получения полного списка.
**Обязательные поля (G2).** При `E_MISSING_FIELD` в `errors[0].data.missing_fields`
(в части ответов — `data.missing`) возвращается список пропущенных имён. Прочитай его и
повтори вызов с полным набором. Не додумывай поля по описанию из Гайда — источник истины
ответ брокера. Перечень обязательных полей WRITE-операций приведён в §1.5, §2.1–§2.3,
§3.1–§3.4.
**`E_BAD_DOC_TYPE` (G3).** Неизвестный или устаревший `doc_type`.
При адресном чтении сохрани исходный запрос и ответ, сообщи о неработающей
ссылке и запроси точные координаты. Не вызывай `list_doc_types` автоматически;
реестр типов используется только в отдельно поставленной задаче диагностики.
### 5.7. Платформенные нормативы и тип `Гайд Пользователя` (разделение a26/a30)
Владельцы платформенных нормативов: ai_docs_broker и adb_meta. Типы:
Онбординг, Гайд Пользователя, Гайд UEPR, Гайд Аудита, Гайд ЖЦ ИТ-продукта H2.
В работающем a26 такие документы владельца допускаются только в prod;
нарушение даёт E_NORM_WRONG_ENV, field=env.
В frozen кандидате a30 есть узкое исключение: только
`env=dev/product=ai_docs_broker/doc_type=Гайд Пользователя`.
Оно позволяет продуктовый dev-гайд ADB после разрешённой установки и публикации,
но не переносит остальные нормативы из prod. a30 сейчас НЕ установлен.
Для продуктов, не являющихся владельцами норматива, этот guard не запрещает
собственный продуктовый документ в их среде. Ни одно правило guard не является
разрешением WRITE в текущем поручении.
created_at/updated_at/added_by строки документа являются реестровыми алиасами
uploaded_at/uploaded_by, не независимой историей создания исходного текста.
### 5.8. Записи журнала работ агентов
`append_agent_work_log` (env + `entry`) и `list_agent_work_log` (read-only,
env-scoped, новейшие сверху) — единый журнал работы агентов; внешний `actor`
остаётся обычным actor-контрактом ADB.
## §6. Что делать, если что-то не работает
**Порядок диагностики:**
1. `health` — сервис жив?
2. `list_products` — продукт зарегистрирован?
3. `list_wheels(product)` — сборка есть?
4. `list_deploys(node, env, status=active)` — деплой активен?
5. `list_documents(product)` — документы на месте?
6. `get_document(doc_id)` — конкретный документ читается?
Если что-то из шагов 1..6 отказало — фиксируйте `error_code` и обращайтесь к ИИ-Архитектору ADB.
**Всё внутреннее — аудит, история, инвентарь узлов, отладка — в Гайде Архитектора v0.16 (doc_id зарегистрируется вместе с этим гайдом).**
---
## §R-RUNTIME. Эксплуатационные слоты
WHEEL: служба запускает установленный non-editable пакет в site-packages своей .venv,
не исходники через PYTHONPATH. Сверяются package metadata, interpreter, entrypoint,
per-file RECORD и SHA wheel. VENV не удаляется ни при обновлении, ни при rollback.
VENV: отдельное штатное окружение продукта; версия Python и зависимости фиксируются
по измерению, а не по версии из чужого UEPR. Общие NATS/БД не заменяются второй копией.
LOG: stdout/stderr и существующая ротация измеряются на узле. Размер ротации
не доказывает bounded-retention; «50MB x10» нельзя писать без правила хранения10.
BACKUP: backup .venv не является backup БД. Нужны идентичность БД, время/размер/
доступность резервной копии и политика; restore требует отдельного разрешения.
Неизвестное поле обозначается UNKNOWN с причиной, а не GREEN по умолчанию.
## Журнал работы и закрытие
Единственный журнал работы — центральный журнал ADB через OWUI Function.
После получения версии из UEPR, до единственного onboard, записать
start_session/started текущим временем; сводку прежних чтений/SHA/разделов
и ошибок по сохранённым ответам API включить в remarks, не переносить
события задним числом. Отдельный локальный журнал, буфер событий
и повторная доставка не создаются.
После фактического чтения нового тела: get_document/ok с разделами и объёмом
чтения; для пробела: gap/ok, ошибки: error/error с причиной.
При readback сверить полноту этих событий с сохранёнными ответами API
и фактическими результатами действий.
Найденный комплект метаданных
учитывать сводкой onboard/ok, не скачиванием и записью на каждую строку.
Использовать ту же OWUI Function; entry содержит известные target_product,
target_node, target_env, task_id, task_url, document_id/type/version/sha256/section.
actor.emitted_at и entry.occurred_at: UTC сейчас с ровно тремя дробными знаками,
`datetime.now(timezone.utc).isoformat(timespec="milliseconds").replace("+00:00","Z")`.
Неизвестное не выдумывать, записи журнала рекурсивно не журналировать.
Lowercase применяется только к машинным меткам env, actor.product/node/session_type,
verb/status, target_product/node/env и document_type записи журнала.
Регистр UUID, URL, task_id, document_version, SHA, document_section, remarks и
временных меток сохраняется. В get_document doc_type канонический, например «Онбординг».
Перед final прочитать все страницы list_agent_work_log с filters.actor_session_id
текущего канонического UUID; проверить env, полноту и учёт ошибок.
После навигационного входа по Онбордингу: final/ready; при неполноте процедуры
или останове: final/blocked. Найденные, но отложенные до задачи подробности
не являются неполнотой входа; found, section_read и fully_read различаются.
Результат онбординга содержит карту из исходных метаданных всех групп
(при большом объёме — отдельное приложение с картой, без хронологии):
канонические doc_type, owui_file_id, координаты, роль, состояние чтения.
Реквизиты не нормализовать подчёркиваниями; текст guide_hint не заменяет
SHA-проверку тела. Краткий CONTEXT_SNAPSHOT в результате фиксирует
сохранённое понимание/ограничения/источники, не скрытые рассуждения.
Итог и карта не дублируют события центрального журнала.
Измерять реальные интервалы с первого инструментального действия;
UTC-границы и измеренные интервалы учитывать в штатных записях центрального
журнала, счётчики вычислять по фактическим ответам;
неполнота карты/SHA/журнала по вине исполнителя не допускает ready.
Отказ append не повторять; больше append в этой сессии нет, ошибка и итог incomplete
фиксируются в итоговом ответе. Доступный обзор завершить и документный план выдать.
Ориентир входа около трёх минут не гарантирует срок и не разрешает скрывать
пробелы. Время входа, задания и всей сессии учитывать отдельно.
Понимание карты проверять уже в задании: агент сразу открывает документ
по сохранённым координатам, читает нужные разделы и отражает выбор
в центральном журнале. Общий поиск заново не выполнять;
точечное обновление допустимо с причиной по Онбордингу. Это не новый гейт
входа. final/ready не означает GREEN продукта. Процедура входа:
`{"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Онбординг","latest":true}`.
## Релиз, установка и критерии GREEN
Цепочка по действующему ЖЦ: frozen source → release manifest и wheel SHA →
разрешённая загрузка и регистрация артефакта с собственным wheel_id →
одобренная установка в существующий единственный runtime → runtime proof →
Guide–Runtime Parity → полный LS с наблюдением → независимый ai_validation →
завершение учёта release/deploy/product state и результатов приёмки → UEPR и аудит.
Первичная регистрация артефакта не означает успешную валидацию или GREEN.
Документ с частичным результатом не отменяет ни одного обязательного шага.
Runtime proof содержит observed_at, product, env, node, release_id, sys_executable,
module_file, package_version, wheel_sha256. Отдельно фиксируются служба, PID,
командная строка, пути и не-editable установка, соответствие файлов wheel RECORD.
Диагностический импорт не выдается за чтение памяти работающего процесса.
Анализ памяти не является дополнительным придуманным обязательным гейтом.
SHA wheel-архива сравнивается с архивом, а файлы пакета с соответствующими членами.
Установка кандидата и перезапуск в этой задаче НЕ выполняются. План установки и
rollback включены в Гайд Пользователя, раздел «Установка и откат a30» (координаты в таблице); перед исполнением
нужны разрешение, актуальный preflight, проверка backup и security.
ЖЦ теперь требует зарегистрировать артефакт после manifest и до установки/LS.
Для кандидата получить его собственный wheel_id и связать с SHA/release manifest;
ID a26 нельзя подставлять a30. Нормативная часть TD-2026-09-19-04 разрешена,
но permission, регистрация кандидата и вся живая цепочка остаются NOT_RUN.
Три независимые оценки:
-_PACKAGE: комплект полон, непротиворечив, SHA/ссылки/хронология проверены.
- OFFLINE_WHEEL: конкретный wheel связан с source и успешными офлайн-тестами.
- INSTALLED_RUNTIME_LIFECYCLE: все обязательные живые гейты пройдены на одном релизе.
Первые две не подменяют третью. Skip/NOT_RUN не считается PASS; total обязан быть >0.
## Установка и откат a30
Статус: подготовленный план, НЕ выполнен. Кандидат `0.9.0a30` прошёл offline-проверки; выполнение на живом `heavy02` требует отдельного разрешения оператора и успешного preflight. Этот встроенный раздел сохраняет установочные команды черновиков R3/R4 в комплекте, но применяет действующий ЖЦ по координатам выше.
### Зафиксированные артефакты
- Кандидат: `ai_docs_broker-0.9.0a30-py3-none-any.whl`, 294616 байт, SHA-256 `6531f7b2501c0f9d89a5ae7166ee0a30b9c93197b03100323e0fd5d51b0580c4`. Files ID `6697bd28-67fa-4512-9eda-cedadedde0d7`.
- Откат: `ai_docs_broker-0.9.0a26-py3-none-any.whl`, 292414 байт, SHA-256 `2763747f218e947d042bf0f77f708a3c885d7050bb9ffbc9dc792c3d86c3a803`. Files ID `9c3df0ab-0788-46ec-8ba0-c6d7e2581ca5`.
- Release UUID: `ed853ff1-88f9-4750-bd2f-aecd648d96ad`.
- Source revision: `3cea4483a7ecd5d14321a17e08954a612b3e6595e314325042d138c77e169aa2`.
Оба wheel были скачаны и проверены по SHA в прежнем evidence; доступность перед исполнением проверить вновь; для отката пересборка не нужна. Новых или изменённых миграций по сравнению с a26 нет.
### Preflight до остановки
1. Получить явное разрешение на обновление единственной службы `h2-ai_docs_broker` на `heavy02`. Разрешение подготовить пакет не разрешает установку.
2. Свежими read-only наблюдениями подтвердить active deploy, health, процесс ADB, интерпретатор, импорт, назначенную БД и единственность runtime. При отличии от baseline a26 остановиться и пересогласовать план.
3. Проверить действующий backup по штатной процедуре узла: охват данных, свежесть, целостность и наличие пригодного восстановления. Наличие файла и его хеш сами по себе не доказывают восстанавливаемость БД. Этот гейт сейчас PENDING.
4. Скачать/разместить оба wheel внутри workspace текущего проекта; сверить точные SHA выше. Не менять глобальный PATH, DSN, runtime-конфигурацию и источник секретов.
5. Снять безопасный снимок конфигурации службы, версии интерпретатора, зависимостей и module paths. Секреты не включать в отчёт.
6. Проверить права, возможность штатной остановки/запуска и доступность отката. Не запускать второй брокер или изолированную БД для проверки.
Подтверждённая кодером конфигурация на момент R4: NSSM `C:\h2\nssm\nssm.exe`, Application `C:\h2\ai_Docs_broker\.venv\Scripts\python.exe`, AppDirectory `C:\h2\ai_Docs_broker`, AppParameters `-m ai_docs_broker`. PID 48428 относится к наблюдению службы; он не подменяет отдельную идентификацию дочернего процесса Python. Перед действиями эти сведения перепроверить.
### Установка после разрешения
1. Штатно остановить только идентифицированную службу; подтвердить завершение её процесса ADB и освобождение launch-lock. Не применять неизбирательный kill и не трогать NATS.
2. Тем же интерпретатором выполнить обычную не-editable установку конкретного проверенного wheel с `--force-reinstall --no-deps`. Существующий venv не удалять, новую среду не создавать.
3. До запуска проверить installed metadata и каждый установленный файл пакета: его относительный путь, размер и SHA должны совпадать с соответствующим файлом внутри принятого wheel. Допустимые создаваемые установщиком файлы учитывать отдельно.
4. Запустить только эту службу. Убедиться, что работает один runtime, health отвечает, БД доступна, launch-lock удерживает правильный процесс.
5. Получить runtime evidence именно из работающего процесса после запуска: `observed_at`, product/env/node, release UUID, `sys.executable`, `module_file`, package version и привязку к SHA принятого wheel. Доказать импорт из `.venv\Lib\site-packages`, отсутствие editable/source-подмены и совпадение файлов работающего пакета.
Не сравнивать SHA каталога либо отдельного `.py` с SHA wheel: это разные байтовые объекты. `pip show` и ответ `health` сами по себе не доказывают происхождение всех импортируемых файлов; health также не следует считать источником SHA, если такого поля в ответе нет.
Пример команд, НЕ выполнявшихся в этой задаче; пути `$CandidateWheel` и `$RollbackWheel` задаются только после проверки SHA:
```powershell
# NOT EXECUTED. Требуются approval и все preflight-гейты.
$Nssm = 'C:\h2\nssm\nssm.exe'
$Python = 'C:\h2\ai_Docs_broker\.venv\Scripts\python.exe'
$Service = 'h2-ai_docs_broker'
# После идентификации службы и готовности отката:
& $Nssm stop $Service
# Проверить остановку именно процесса ADB и освобождение его lock.
& $Python -m pip install --force-reinstall --no-deps $CandidateWheel
# Проверить код возврата, installed files vs wheel RECORD и metadata.
& $Nssm start $Service
# Теперь health, runtime evidence, process/lock и мониторинг.
```
### Проверки после установки
Единый порядок: runtime proof → канонический dev-guide и Guide–Runtime Parity → полный Live Scenario с мониторингом → независимый специальный агент `ai_validation` → завершение учёта release/dev-deploy/product-state → полный UEPR и аудит.
Нельзя объявить полный ЖЦ зелёным на основании offline-тестов. Предыдущий комплект документов опубликован, UEPR описывает a26; нынешние правки одобрены для публикации. Исторические времена измерений не меняются.
#### Нормативная зависимость wheel_id
Прежняя зависимость устранена ЖЦ v0.5: после release manifest, до установки и зачётного LS, артефакт загружается и регистрируется с собственным wheel_id. Регистрация связывает SHA и release manifest, но не означает приёмку. После LS и ai_validation завершается учёт release. Для исполнения требуется отдельное разрешение Оператора; запрещено использовать wheel109 от a26 для a30.
Это не блокирует наличие проверенного бинарного кандидата, но не позволяет обещать полную приёмку ЖЦ без решения зависимости. План не санкционирует обход гейта.
### Откат
Если установка, запуск или обязательные проверки не проходят, остановить только идентифицированную службу и установить сохранённый a26 тем же интерпретатором с `--force-reinstall --no-deps`. Затем запустить единственную службу и проверить фактические runtime version, interpreter, import paths, файлы относительно a26 RECORD, процесс, lock, health и доступность БД.
Старая запись `get_active_deploy` не является доказательством отката процесса. Изменение реестра, если оно уже произошло, оформляется отдельно и прозрачно; данные и историю не удалять и не восстанавливать из устаревшего снимка автоматически. При невозможности безопасного восстановления остановиться и сообщить точное состояние, без циклов рестартов.
## ИСТОРИЯ: точное полное тело родителя, НЕ АКТИВНО
Ниже сохранена прежняя версия для проверки кумулятивности. Старые actor, principal, HMAC, разрешения, версии, результаты и команды не исполняются.
# ADB Гайд Пользователя v0.34
**Дата:** 2026-09-18
**Продукт:** ai_docs_broker
**Prod-версия:** 0.9.0a26 (heavy02)
**Родитель:** v0.33 (doc_id=632)
**Кумулятивно к:** v0.7 → v0.22 → v0.26..v0.29 → v0.30..v0.33 (весь op-каталог собран заново, не delta).
**Что нового (v0.34):** новый раздел §5.7 «Платформенные нормативы и тип `Гайд Пользователя`» — перечень типов-нормативов платформы, их владелец, требование по среде, код `E_NORM_WRONG_ENV` и условия его появления; отдельно описано, что документ продукта того же типа проверкой норматива не затрагивается. Также зафиксировано, что строка документа в `get_document`/`list_documents` несёт `created_at`/`updated_at`/`added_by`. Основание: CR-ADB-2026-09-18-NORM (дефект Б-13, регрессия платформы).
**Что было в v0.33:** §3.2 `deprecate_document` — `deprecated_by` убрано из обязательных полей.
---
## §1. Простой минимум — 9 операций для 90% работы
Если вы никогда не работали с ADB, начните только с этих 9. Все остальные разделы читайте, когда понадобится.
### 1.1 `health` — проверить, что сервис жив
**Зачем:** первый вызов при подозрении что что-то не так.
**Ключевые поля запроса:** `env` (`prod` или `dev`).
**Ключевые поля ответа:**
- `status='ok'` — сервис отвечает.
- `broker_version` — версия wheel (например, `0.9.0a12`).
- `uptime_s` — сколько работает.
**Пример:**
```json
{"op":"health","env":"prod"}
```
### 1.2 `onboard` — получить пакет документов продукта одним вызовом
**Зачем:** это **первый вызов ИИ-Исполнителя** и любого клиента, который хочет получить всё нужное для работы с продуктом за один шаг.
**Ключевые поля запроса:**
- `env` — `prod` или `dev`.
- `product` — имя продукта (например, `ai_docs_broker`).
- `node` — узел (например, `heavy02`), опционально.
- `include_texts=true` — вернуть тексты документов в ответе (без этого только метаданные).
**Ключевые поля ответа:**
- `ready` (`true`/`false`) — удалось ли собрать пакет.
- `docs.<doc_type>` — актуальный документ по каждому типу.
- `adb_self.user_guide` — этот гайд.
- `transports.*.user_guide` — гайды транспортов, которые продукт использует.
- `onboarding_ref` — ссылка на актуальный Онбординг Исполнителя.
**Что делать, если `ready=false`:** пакет неполный. Смотреть `reasons` в ответе и добирать точечно через `get_document`.
**Пример:**
```json
{"op":"onboard","env":"prod","product":"ai_docs_broker","include_texts":true}
```
### 1.3 `get_document` — прочитать конкретный документ
**Зачем:** точечное чтение одного документа, если `onboard` не подошёл или нужен архивный.
**Три способа выбрать документ:**
1. По `doc_id` — самый прямой:
```json
{"op":"get_document","env":"prod","doc_id":562}
```
2. По `(product, doc_type)` — вернёт **актуальную** версию:
```json
{"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Дорожная Карта"}
```
3. По `(product, doc_type, version)` — конкретная версия (актуальная или архивная):
```json
{"op":"get_document","env":"prod","product":"ai_docs_broker","doc_type":"Дорожная Карта","version":"v0.40"}
```
**Ключевые поля ответа:**
- `row.id`, `row.version`, `row.owui_file_id`, `row.sha256`, `row.filename` — метаданные.
- `text` — полный текст (если запрошен `include_text=true`, по умолчанию `true` для актуальных).
**Ошибки:**
- `E_NOT_FOUND` — документа нет.
- `E_BAD_DOC_TYPE` — `doc_type` не в реестре или устарел; регистр и пробелы значимы.
При адресном чтении сообщи о неработающей ссылке и запроси точные координаты.
Предварительное чтение реестра типов не требуется, в том числе cloud-клиентам
и клиентам первого запуска. `data.allowed`, если оно получено, можно передать
Постановщику как часть ответа; оно не разрешает самостоятельную замену типа.
### 1.4 `list_documents` — список документов по продукту/типу
**Зачем:** узнать, какие документы есть.
**Ключевые поля запроса:**
- `env`, `product` (обязательно), `doc_type` (опционально — фильтр).
- `limit`, `offset` — пагинация.
**Ключевые поля ответа:**
- `rows[]` — только **актуальные (не deprecated)**, каждая с `{id, version, filename, sha256, uploaded_at, deprecated}`.
**Пример:** «покажи все Гайды Пользователя ADB»:
```json
{"op":"list_documents","env":"prod","product":"ai_docs_broker","doc_type":"Гайд Пользователя"}
```
### 1.5 `register_document` — загрузить документ
**Зачем:** добавить новый документ (гайд, отчёт, UEPR, дор карта, TDL).
**Обязательные поля (G2, эмпирически a33 — `errors[0].data.missing_fields`):**
`env`, `product`, `doc_type`, `version`, `owui_file_id`, `filename`, `sha256`.
`size` опционален (для публикации передаётся измеренный размер). `parent_doc_id` —
опциональная связь версии (поля `parent_id` нет). `uploaded_by` вычисляется брокером из actor.
**Как получить `owui_file_id` и `sha256`:** сначала аплоад через OWUI Files API (`POST /api/v1/files/`), в ответе — `file_id`. `sha256` считается локально по содержимому файла.
**Пример:**
```json
{
"op":"register_document","env":"prod","product":"ai_docs_broker",
"doc_type":"Дорожная Карта","version":"v0.41",
"owui_file_id":"2512928d-4f6d-...","sha256":"77c107b9...","filename":"roadmap_v041.md","size":18093,
"parent_id":528,"uploaded_by":"andy.krivenko@gmail.com",
"comment":"5 новых задач"
}
```
**Что вернётся при успехе:** `data.new_id` (id новой строки), `data.created=true`, `data.row` — вся зарегистрированная строка.
**Основные ошибки:**
- `E_MISSING_FIELD` — пропущено обязательное поле.
- `E_DELTA_NOT_CUMULATIVE` (после 0.9.0a14) — вы регистрируете delta для кумулятивного типа. Соберите полный кумулятивный текст.
- `E_BAD_VERSION_RANGE` — версия не в PEP-440 (см. §5.3).
### 1.6 `list_products` — какие продукты вообще есть
**Пример:**
```json
{"op":"list_products","env":"prod"}
```
**Ответ:** `rows[]` — все продукты с `{name, runtime, kind, created_at}`.
### 1.7 `list_wheels` — какие сборки продукта есть
**Пример:**
```json
{"op":"list_wheels","env":"prod","product":"ai_docs_broker"}
```
**Ответ:** `rows[]` — сборки с `{id, version, sha256, wheel_url, uploaded_at, uploaded_by}`, сортировка по времени.
### 1.8 `list_deploys` — что развёрнуто на узле
**Важно:** ответ — **тонкая проекция**, содержит только `{node, env, status, product, product_version}`. `id`, `sha256`, `filename` **не возвращаются**. Чтобы получить полную запись — используйте `get_active_deploy` (см. §4.1).
**Пример:**
```json
{"op":"list_deploys","env":"prod","node":"heavy02","status":"active"}
```
**Ответ:** `rows[]` — активные деплои на узле.
### 1.9 `list_nodes` — какие узлы платформы есть
**Пример:**
```json
{"op":"list_nodes","env":"prod"}
```
**Ответ:** `rows[]` с `{node, env, active_deploys_count, last_seen_at}`.
---
## §2. Жизненный цикл сборки — 5 операций
Когда вы выкатываете новую версию продукта.
### 2.1 `register_product` — завести новый продукт
**Когда:** до первого `register_wheel`, если продукта ещё нет в `list_products`.
**Обязательные поля (G2, эмпирически a33):** `env`, `product` (lower_snake_case, только
`[a-z][a-z0-9_]*`). `runtime` и `kind` — **вымышленные** обязательные поля, брокер их не
требует; опциональны: `product_type`, `parent`, `display_name`, `description`.
**Пример:**
```json
{"op":"register_product","env":"prod","product":"my_agent","runtime":"python","kind":"agent"}
```
**Ошибки:**
- `E_INVALID_PRODUCT_NAME` — имя не в lower_snake_case.
- `E_ALREADY_EXISTS` — уже зарегистрирован.
### 2.2 `register_wheel` — зарегистрировать сборку
**Обязательные поля (G2, эмпирически a33):** `env`, `product`, `wheel_version`, `sha256`,
`size`, `filename`. Legacy `version` принимается с предупреждением. `wheel_url` не заменяет
`filename`/`owui_file_id`; `uploaded_by` формируется брокером из actor.
**Формат `version`:** **PEP-440 без пре-дефиса**. Правильно: `0.9.0a12`, `0.9.0`, `0.0.1a1+ls62de9349`. Неправильно: `0.9.0-a12`, `0.0.1-hex` — оба дают `E_BAD_VERSION_RANGE`.
**Пример:**
```json
{
"op":"register_wheel","env":"prod","product":"ai_docs_broker",
"version":"0.9.0a12","sha256":"abc...","wheel_url":"file:///wheels/ai_docs_broker-0.9.0a12.whl",
"size":123456,"uploaded_by":"andy.krivenko@gmail.com"
}
```
**Ответ:** `data.new_id` — id новой сборки, `data.row` — вся запись.
### 2.3 `register_deploy` — зафиксировать деплой
**Обязательные поля (G2, эмпирически a33):** `env`, `product`, `node`, `wheel_id`.
Произвольный `status` не передаётся (новая запись active, прежние active → superseded);
`deployed_by` формируется брокером из actor.
**Пример:**
```json
{
"op":"register_deploy","env":"prod","product":"ai_docs_broker",
"node":"heavy02","wheel_id":76,"status":"active","deployed_by":"andy.krivenko@gmail.com"
}
```
**Ответ:** `data.new_id` — id новой записи деплоя.
### 2.4 `get_wheel` — прочитать запись wheel
**Пример:**
```json
{"op":"get_wheel","env":"prod","wheel_id":76}
```
**Ответ:** `row` с `{id, product, version, sha256, wheel_url, size, uploaded_at, uploaded_by}`.
### 2.5 `get_product` — прочитать запись продукта
**Пример:**
```json
{"op":"get_product","env":"prod","product":"ai_docs_broker"}
```
**Ответ:** `row` — метаданные продукта, включая `runtime`, `kind`, зависимости.
---
## §3. Работа с уже загруженными документами — 4 операции
### 3.1 `update_document` — поправить комментарий/метаданные
**Обязательные поля (G2, эмпирически a33):** `env`, `doc_id` + непустое изменение метаданных.
**Меняет только:** `comment`, `applies_to_version_range`, `review_status`. **Не меняет** `sha256`, `owui_file_id`, `version` — для нового содержимого регистрируйте новую версию.
**Пример:**
```json
{
"op":"update_document","env":"prod","doc_id":562,
"comment":"уточнение по §NEW-3","updated_by":"andy.krivenko@gmail.com"
}
```
### 3.2 `deprecate_document` — убрать документ из актуальных
**Обязательные поля (G2, эмпирически a33):** `env`, `product`, `doc_id`, `retired_reason`
(именно `retired_reason`, не `reason`, непустой) и полный `actor` (7 required-полей).
**Опциональные:** `deprecated_by` — принимается, но не обязателен. Прежние версии Гайда (v0.30..v0.32) ошибочно объявляли его required; фактический контракт брокера 0.9.0a14+ его не требует (доказано в TDL v47 TD-2026-09-17-02).
**Пример:**
```json
{
"op":"deprecate_document","env":"prod","product":"ai_docs_broker",
"doc_id":558,"retired_reason":"replaced by v0.30 consolidated",
"actor":{ ...полная схема 7 required... }
}
```
**Ответ:** `data.archive_id` — id архивной записи. После этого `get_document(doc_id=558)` вернёт `E_NOT_FOUND`, а `list_document_archive` найдёт запись.
**Известный баг (TDL v47 TD-2026-09-17-04, OPEN):** после `deprecate_document` в архивной записи `retired_reason` пишется `null`, `archive_reason="delete"`. Само действие проходит, но обоснование теряется. Целевой фикс — 0.9.0a15.
### 3.3 `bulk_deprecate_documents` — массовая архивация
**Обязательные поля (G2, эмпирически a33):** `env`, `filter`, `comment`; `dry_run` по
умолчанию `true`.
**Пример:**
```json
{
"op":"bulk_deprecate_documents","env":"prod","product":"ai_docs_broker",
"doc_ids":[483,414,231],"retired_reason":"consolidation to v0.30",
"deprecated_by":"andy.krivenko@gmail.com"
}
```
**Ответ:** `data.deprecated_count`, `data.doc_ids`.
### 3.4 `promote_document` — продвинуть dev → prod
**Зачем:** взять документ из `env=dev` и создать его копию в `env=prod`.
**Обязательные поля (G2, эмпирически a33):** `env`, `from_env`, `to_env`, `doc_id`.
**Пример:**
```json
{
"op":"promote_document","env":"prod","source_env":"dev",
"source_doc_id":561,"promoted_by":"andy.krivenko@gmail.com"
}
```
**Ответ:** `data.new_id` — id новой записи в prod.
---
## §4. Точечное чтение — 3 операции
### 4.1 `get_active_deploy` — текущий активный деплой продукта на узле
**Ключевые поля запроса:** `env`, `product`, `node`.
**Пример:**
```json
{"op":"get_active_deploy","env":"prod","product":"ai_docs_broker","node":"heavy02"}
```
**Ответ:** `row` — полная запись деплоя с `{id, wheel_id, sha256, version, deployed_at}`.
### 4.2 `get_document_for_node` — документ, применимый к конкретному узлу
**Зачем:** документ может иметь `applies_to_version_range`. Эта op учитывает какая версия продукта развёрнута на узле и возвращает подходящий документ.
**Пример:**
```json
{
"op":"get_document_for_node","env":"prod","product":"ai_docs_broker",
"doc_type":"Гайд Пользователя","node":"heavy02"
}
```
**Ответ:** `row` документа, применимого к активной сборке на узле.
### 4.3 `list_products_state` — статус продуктов по узлам
**Пример:**
```json
{"op":"list_products_state","env":"prod"}
```
**Ответ:** `rows[]` — по каждому продукту на каждом узле `{product, node, state, last_reported_at, wheel_id}`.
---
## §5. Стандарты и правила
### 5.1 Актор (обязателен на всех WRITE-op)
WRITE-операции (`register_*`, `update_*`, `deprecate_*`, `promote_*`, `set_*`) требуют актор-контекст.
**Как формируется актор (уточнено в v0.31):**
1. **Если клиент передал `actor` в теле операции** — используется **actor клиента как есть**, без подмены. OWUI-фасад пробрасывает его в брокер целиком (проверено через `op=echo`).
2. **Если клиент НЕ передал `actor` в теле** — OWUI-фасад подставляет свой дефолтный actor (`principal=owui_client`, `session_type=owui`, `session_id=unknown`, без `source_url`). Этот actor **не проходит** валидацию для большинства WRITE-op — ты получишь `E_ACTOR_REQUIRED` или `E_MISSING_ACTOR_FIELD`.
**Практическое правило:** ИИ-агент **всегда** передаёт свой полный actor в теле операции. Никогда не полагайся на автоподстановку фасада — она предназначена только для legacy read-only клиентов без credential.
**Обязательные 7 полей актора (по факту брокера 0.9.0a14, `broker_hints.required_fields`):**
- `product`, `node`, `product_version`
- `session_type`, `session_id`, `request_id`, `emitted_at`
**Рекомендуемые дополнительные поля (для аудита):**
- `principal` — email пользователя или `svc:<name>`. Пишется в `actor_principal` в audit-таблице.
- `source_url` — полный URL сессии-инициатора (для Perplexity — `https://www.perplexity.ai/computer/tasks/<UUID>`). Передаётся брокеру, но в audit-таблицу пока не пишется (см. tech-debt TD-2026-09-17-07).
**Устаревшие поля actor** (Гайд ≤ v0.30 их требовал, брокер 0.9.0a14 — не требует и игнорирует):
- `hmac_phase` — HMAC полностью удалён в 0.9.0a9, оставить `"removed"` только для маркировки; отсутствие не влияет.
- `caller_kind` — не в `required_fields`, отсутствие не влияет.
**G4 — `__unknown__`-клиенты и порядок получения версии.** Клиенты, получившие
`E_ACTOR_MISSING_VERSION` или `E_ACTOR_REQUIRED`, обязаны выполнить Онбординг:
`{"op":"onboard","product":"<product>","node":"<node>","env":"<env>"}` получает пакет
документов включая UEPR. `actor.product_version` берётся из SHA-проверенного тела UEPR и
**не выводится** из header, каталога установки, сервисной metadata или подстановки
`product_version_source=active_deploy`. Bootstrap `get_document` для UEPR разрешён без
`product_version`, но требует остальные поля actor. Клиент, идентифицирующий себя как
`product=__unknown__` и `node=__unknown__`, гарантированно получает
`E_ACTOR_MISSING_VERSION` или `E_ACTOR_REQUIRED` и должен исправить конфигурацию до
следующего вызова.
### 5.2 HMAC-подпись
**HMAC полностью удалён из ADB в 0.9.0a9** (миграция 033). Клиент **не подписывает** запросы. Поле `hmac_phase='removed'` в акторе — маркер для аудита.
### 5.3 Версии — PEP-440
- `register_wheel.version` — PEP-440 без пре-дефиса: `0.9.0a12`, `0.9.0`, `0.0.1a1+ls62de9349`.
- `applies_to_version_range` — PEP-440 с дефисом (странность, будет исправлена в 0.9.0a13, см. TDL TD-2026-09-16-04): `>=0.9.0-a11`, `<1.0.0-0`.
- Диапазоны: `>=X,<Y`, `>=X`, `<Y`, `=X` (не `==X` до 0.9.0a13).
- **`actor.product_version` — тоже PEP-440 без пре-дефиса.** Правильно: `0.7.27`, `0.7.27a1`, `0.7.27.dev1`, `0.7.27+dev`. **Неправильно: `0.7.27-dev`, `1.0-beta`, `v1.2.3`** (дефис вне PEP-440).
- До 0.9.0a15 — при провале брокер возвращает **обобщённое** `E_ACTOR_REQUIRED` (сбивает с толку). После 0.9.0a15 (ADB-111) — специфичное `E_BAD_ACTOR_PRODUCT_VERSION` с указанием невалидного значения и примерами валидных форм. См. TDL TD-2026-09-17-09.
- **Симптом до фикса:** actor полностью собран (все 7 required), `source_url` есть, но брокер отвечает `error_code=E_ACTOR_REQUIRED, message="actor is required ..."`. Первое что проверить — форма `actor.product_version`.
### 5.4 Имена продуктов
Только lower_snake_case: `^[a-z][a-z0-9_]*$`. Валидация на входе `register_product` / `register_document` / `bulk_deprecate_documents`.
### 5.5 Кумулятивные документы (T-DOCS-14 + T-DOCS-DELTA-BAN)
**Кумулятивные типы** (после 0.9.0a14 с валидатором):
- Гайд Пользователя
- Гайд Архитектора
- Дорожная Карта
- Онтология
- Концепт Развития
- Стандарт (tech-debt-log)
- Live Scenario
- Онбординг
**Правило:** каждая новая версия — **целый полный текст**, не «delta vs предыдущий». Ссылки типа «Всё из v0.28 остаётся в силе» запрещены. Разрешено в конце файла добавить раздел «§CHANGELOG» с diff от предыдущей версии.
**Валидация при `register_document`** (после 0.9.0a14):
- Файл не начинается с «Delta vs vN» и не содержит «Остальное — без изменений» в первых 30 строках.
При нарушении — `E_DELTA_NOT_CUMULATIVE`, `data.rule` называет правило.
**Планируется в 0.9.0a15 (TD-2026-09-17-08):** заменить проверки размера на валидатор `§CHANGELOG <new_version> vs <parent_version>` в тексте. См. TDL v45-r1 TD-08.
**Некумулятивные типы** (upsert-слот, cumulative-check не применяется):
- Отчёт Валидации
- Отчёт Приёмки
- Бриф
- UEPR
- Гайд Аудита
### 5.6 Ошибки — общий формат
```json
{
"status":"error","error_code":"E_XXX",
"errors":[{"code":"E_XXX","message":"...","class":"input|validation|auth|storage|internal","field":"...","hint":"..."}],
"data":{...}
}
```
**Основные `error_code` пользователя:**
- `E_MISSING_FIELD` — обязательное поле не передано (список в `data.missing_fields`).
- `E_INVALID_PRODUCT_NAME` — имя не lower_snake_case.
- `E_BAD_VERSION_RANGE` — версия не PEP-440.
- `E_NOT_FOUND` — сущность не найдена.
- `E_ALREADY_EXISTS` — такая уже есть (для register-op).
- `E_BAD_DOC_TYPE` — `doc_type` не в реестре или deprecated (`E_DOC_TYPE_DEPRECATED`).
При адресном чтении сообщить о неработающей ссылке и запросить точные координаты;
поиск через `list_doc_types` допустим только как отдельно поставленная диагностика.
- `E_DELTA_NOT_CUMULATIVE` (после 0.9.0a14) — попытка зарегистрировать delta для кумулятивного типа.
- `E_UNKNOWN_OP` — неизвестная операция. Ответ содержит `errors[0].data.known_ops` —
полный список действующих операций; используйте его как источник истины (см. discovery ниже).
**Discovery операций (G1).** Публичного `list_ops` нет. Список действующих операций
получается стандартным механизмом ошибки: любой неизвестный `op` даёт ответ
`status=error`, `error_code=E_UNKNOWN_OP`, `errors[0].data.known_ops = [...]` (на
runtime a33-пары список содержит 59 имён). Пример проверочного запроса:
`{"op":"__discover__"}`. Имена операций `snake_case` и регистр-чувствительны.
`ping`, `help`, `capabilities`, `describe`, `version`, `operations`, `list_operations`,
`upload_file`, `put_document`, `upload_document` **не являются** операциями брокера.
Не строить клиентскую логику на fingerprinting произвольными именами: одного вызова с
известным неверным op достаточно для получения полного списка.
**`E_MISSING_FIELD` (G2).** В `errors[0].data.missing_fields` (в части ответов —
`data.missing`) возвращается список пропущенных имён. Прочитайте его и повторите вызов с
полным набором. Не додумывайте поля по описанию из Гайда — источник истины ответ брокера.
Перечень обязательных полей WRITE-операций — в §1.5, §2.1–§2.3, §3.1–§3.4.
---
### 5.7. Платформенные нормативы и тип `Гайд Пользователя` (новое в v0.34)
Не все типы документов равны. Часть имён `doc_type` относится к **платформенным
нормативам** — документам самой платформы H2 (регламенты, гайды, онбординги),
которые ведёт и хранит владелец норматива. Проверка «норматива платформы»
применяется ТОЛЬКО когда целевой продукт и есть владелец норматива.
| Что | Значение |
|---|---|
| Владельцы норматива | `ai_docs_broker`, `adb_meta` |
| Типы-нормативы платформы | `Онбординг`, `Гайд Пользователя`, `Гайд UEPR`, `Гайд Аудита`, `Гайд ЖЦ ИТ-продукта H2` |
| Требование по среде | владелец норматива регистрирует его ТОЛЬКО в `env=prod` |
| Код отказа | `E_NORM_WRONG_ENV` (`class=validation`, `field=env`) |
**Документ продукта того же типа — не норматив.** Если `product` не входит в
список владельцев норматива, тип `Гайд Пользователя` (равно как `Онбординг`,
`Гайд UEPR` и прочие типы того же перечня) — обычный документ продукта: он
регистрируется в своей среде (`env=dev` для продукта с картой `dev_only`) и
проверкой норматива не затрагивается. Так каждое ИТ-продукт ведёт **свой**
`Гайд Пользователя` в своём контуре.
**Когда появляется `E_NORM_WRONG_ENV`.** Отказ выдаётся только при реальном
расхождении: владелец норматива (`ai_docs_broker`/`adb_meta`) пытается
зарегистрировать тип-норматив не в `env=prod`. Поля отказа:
```json
{
"code": "E_NORM_WRONG_ENV", "class": "validation", "field": "env",
"data": {"expected": "prod", "received": "<присланная среда>",
"product": "<владелец норматива>", "doc_type": "<тип>"}
}
```
Если `expected == received` (среда совпала), отказа нет — сообщение и `field`
отражают фактическую причину (среда владельца норматива), а не имя типа.
**Происхождение документа.** Строка документа в `get_document` и
`list_documents` несёт непустые `created_at`, `updated_at` и `added_by`
(для реестра `created_at`/`updated_at` — время регистрации/последней записи
версии, `added_by` — кто зарегистрировал).
### 5.8. Записи журнала работ агентов
`append_agent_work_log` (env + `entry`) и `list_agent_work_log` (read-only,
env-scoped, новейшие сверху) — единый журнал работы агентов; внешний `actor`
остаётся обычным actor-контрактом ADB.
## §6. Что делать, если что-то не работает
**Порядок диагностики:**
1. `health` — сервис жив?
2. `list_products` — продукт зарегистрирован?
3. `list_wheels(product)` — сборка есть?
4. `list_deploys(node, env, status=active)` — деплой активен?
5. `list_documents(product)` — документы на месте?
6. `get_document(doc_id)` — конкретный документ читается?
Если что-то из шагов 1..6 отказало — фиксируйте `error_code` и обращайтесь к ИИ-Архитектору ADB.
**Всё внутреннее — аудит, история, инвентарь узлов, отладка — в Гайде Архитектора v0.16 (doc_id зарегистрируется вместе с этим гайдом).**
---
## §CHANGELOG v0.34 vs v0.33
1. **§5.7 (новый).** Платформенные нормативы: перечень типов (`Онбординг`,
`Гайд Пользователя`, `Гайд UEPR`, `Гайд Аудита`, `Гайд ЖЦ ИТ-продукта H2`),
владелец (`ai_docs_broker`/`adb_meta`), требование `env=prod` для владельца,
код `E_NORM_WRONG_ENV` и условия его появления.
2. **Разделение норматива и документа продукта.** Тип `Гайд Пользователя`
продукта, не являющегося владельцем норматива, регистрируется как обычный
документ продукта (в т.ч. в `env=dev`). Раньше отклонялся любой продукт,
кроме `ai_docs_broker` — регрессия платформы (дефект Б-13).
3. **Сообщение и `field` отказа** приведены к фактической причине; неверная
подсказка «`Гайд Пользователя` принадлежит `product=ai_docs_broker`» убрана.
4. **§5.7 (происхождение).** `created_at`/`updated_at`/`added_by` в строке
документа `get_document`/`list_documents`.
5. **Основание.** CR-ADB-2026-09-18-NORM (Запрос на Изменение cr-v0.4, §3.6
Б-13); брокер 0.9.0a26.
§END v0.34
## §CHANGELOG v0.33 vs v0.32
**Одно точечное исправление контракта §3.2 (без изменения остального op-каталога).**
1. **§3.2 `deprecate_document`.** Поле `deprecated_by` убрано из обязательных. Фактический контракт брокера 0.9.0a14+ требует только `env`, `product`, `doc_id`, `retired_reason` (непустой), `actor` (7 required-полей). `deprecated_by` — опциональный.
2. **Основание.** TDL v47 TD-2026-09-17-02 CLOSED (doc_id=627). Лично перепроверено Постановщиком перед публикацией v0.33 — dev-проба: `register_document(env=dev, doc_type='Live Scenario', ...)` → `new_id=631`; затем `deprecate_document(doc_id=631, retired_reason="probe: verify deprecated_by is optional", actor=...)` без поля `deprecated_by` → `status=ok`, `archive_id=967`, correlation `30e1223d-5a95-43cd-ae1e-8f839631f2e0` (2026-09-17 13:32 UTC).
3. **Добавлено в §3.2 предупреждение:** известный баг TD-2026-09-17-04 (OPEN) — `retired_reason` в архивной записи пишется `null`. Целевой фикс — 0.9.0a15.
§END v0.33
---
## §CHANGELOG v0.30
**Пересборка целиком, кумулятивно к v0.7 → v0.22 → v0.26..v0.29.**
**Что изменилось vs v0.29:**
1. **21 user-op** вместо 48 (сюда включены только те, что нужны внешнему пользователю). Из v0.29 удалены 29 arch-op — они переехали в Гайд Архитектора v0.16.
2. **§1 «Простой минимум — 9 операций для 90% работы»** — новый первый раздел, вперёд всего каталога.
3. **§5.3** уточнено: `register_wheel.version` — PEP-440 без пре-дефиса; `applies_to_version_range` — с дефисом (расхождение зафиксировано в TDL TD-2026-09-16-04).
4. **§5.5** новый: правило T-DOCS-DELTA-BAN (кумулятивные документы), список кумулятивных / некумулятивных типов, ожидаемая ошибка `E_DELTA_NOT_CUMULATIVE`.
5. **§3.2** `deprecate_document`: явно указаны обязательные `retired_reason` (не `reason`) и `product`.
6. **§1.8** `list_deploys`: явно описана тонкая проекция, `id`/`version` не возвращаются, полная запись — через `get_active_deploy`.
7. **§1.2** `onboard`: описан как **первый вызов**, а не как альтернатива серии `get_document`.
§END v0.30
---
## §CONSOLIDATION
**Версия:** `v0.30-consolidated`. Полный кумулятивный текст для `Гайд Пользователя`. Актуальная версия `564` сохранена первой; ниже сохранены все доступные предыдущие версии этой линии для буквенной непрерывности секций. Это не delta-документ: нормативный актуальный текст находится выше, исторические снимки добавлены только для проверки эволюции.
## §HISTORICAL-PRESERVATION
### Исходная версия 0.10 (doc_id=112)
# Гайд Пользователя ai_Docs_broker v0.10
**Уровень:** L3 (Гайд Пользователя)
**Статус:** актуальный, целевая wheel `0.4.3` (Stage 5 in progress); до релиза 0.4.3 действует §7A (fallback 0.4.2)
**Дата:** 2026-09-06
**Заменяет:** Гайд v0.9 (Stage 5: enforce-фаза HMAC, обязательные серверные секреты, аудит-операции `list_caller_events`/`who_touched`, `rotate_node_credential`, migration 008, bootstrap_mode enforce, retention)
---
## Что нового в этой версии
Stage 5 wheel `0.4.3` вводит enforce-фазу HMAC и закрывает T-STAGE4-01 (обязательные серверные секреты):
1. **`ADB_HMAC_REQUIRE_SECRETS=true` по умолчанию.** Сервис 0.4.3 fail-fast без `ADB_KEK` и `ADB_BOOTSTRAP_SECRET`. Оператор обязан положить их в `C:/h2/ai_Docs_broker/.env` перед перезапуском.
2. **`actor_phase='enforce'` для write-ops.** Регистр операций без `actor` → `E_ACTOR_REQUIRED`. Клиент `client_version ≥ 0.1.1` без HMAC → `E_HMAC_REQUIRED`. Read-ops остаются без обязательного actor (fallback для legacy — §5).
3. **Аудит-операции появились.** `list_caller_events` и `who_touched` теперь доступны (см. §6). Оба требуют actor.
4. **`rotate_node_credential`** — новая write-операция для ротации HMAC-secret (см. §6, §11).
5. **Migration 008.** При старте сервиса с `ADB_KEK` `hmac_secret_enc` пере-упаковывается из plaintext (fallback 0.4.2) в Fernet — идемпотентно.
6. **`bootstrap_mode` enforce.** Insecure credentials из fallback 0.4.2 продолжают работать, но в каждом ответе получают `broker_hints.warnings[].code=must_rotate` — обязательно вызвать `rotate_node_credential` в течение 30 суток.
7. **Retention.** Cron-скрипт `_ops/cleanup_caller_events.py` удаляет записи `caller_events` старше 30 суток.
Вся actor-логика v0.9 сохраняется. `include_nodes` по-прежнему не поддерживается.
**Совместимость:** Гайд v0.10 применим начиная с 0.4.3. Для 0.4.2 продолжайте использовать v0.9 (см. §7A).
---
## 1. Быстрый старт для нового ИТ-продукта
### Шаг 1. Зарегистрировать узел
Через OWUI-функцию `h2_ai_docs_broker_function`. Все поля payload идут в top-level (не в `params`):
```json
{
"op": "register_node",
"node_id": "your-node-id",
"class": "light",
"purpose": "описание назначения узла",
"registered_by": "your.email@example.com",
"actor": {
"product": "your_product_name",
"node": "your-node-id",
"product_version": "0.1.0",
"session_type": "cli",
"session_id": "bootstrap-2026-09-06",
"principal": "your.email@example.com",
"request_id": "<uuidv4>",
"emitted_at": "<now RFC3339>"
}
}
```
**Поля узла (обязательные):**
| Поле | Значения | Пример |
|---|---|---|
| `node_id` | slug, ≤64 символов, уникален | `laptop-01`, `heavy02` |
| `class` | enum: `heavy`, `light`, `laptop` | `light` |
| `purpose` | свободный текст, ≤256 символов | `dev-runtime for h2_openbrowser` |
| `registered_by` | email или `svc:name` | `andy.krivenko@gmail.com` |
**Идемпотентность:** повторный `register_node` с тем же `node_id` не создаёт дубликат — возвращает `updated=true`.
**Bootstrap HMAC (Stage 4, wheel 0.4.2+):** в ответе появится `node_credentials.key_id` и `hmac_secret` (одноразовый показ). Сохранить в keyring узла командой:
```bash
python -c "import keyring; keyring.set_password('h2-adb', '<key_id>', '<secret>')"
```
В shadow-фазе (0.4.1) HMAC ещё не выдаётся — узел просто регистрируется в реестре.
### Шаг 2. Установить клиентскую library
```bash
pip install ai_docs_broker_client
```
### Шаг 3. Создать `~/.h2/actor.toml`
```toml
[actor]
product = "your_product_name"
node = "your-node-id"
product_version = "0.1.0"
principal = "your.email@example.com"
[credential]
key_id = "<из шага 1>"
# hmac_secret не в файле - через keyring:
# python -c "import keyring; keyring.set_password('h2-adb', '<key_id>', '<secret>')"
```
### Шаг 4. Использовать client в коде
```python
from ai_docs_broker_client import ADBClient
adb = ADBClient() # читает actor.toml и keyring автоматически
# Read (actor желателен, HMAC не нужен):
doc = adb.get_document(doc_type="user_guide", product="ai_docs_broker")
# Write (actor + HMAC обязательны в enforce phase):
adb.register_document(
doc_type="report",
product="your_product_name",
version="0.1.0",
content_owui_file_id="<owui_file_id>",
session_type="roo", # или из ENV H2_SESSION_TYPE
session_id="<sid>", # или из ENV H2_SESSION_ID
)
```
---
## 2. Actor schema — поля
| Поле | Обязат. | Формат | Пример |
|---|---|---|---|
| `product` | да | snake_case, ≤64 символов | `h2_openbrowser` |
| `node` | да | kebab-case, ≤64 | `laptop-01` |
| `product_version` | да | PEP 440 local version | `0.4.0+sha256.3053557e` |
| `session_type` | да | enum | `roo\|perplexity\|owui\|cli\|service\|cron` |
| `session_id` | да | slug (не URL) | `01a07338-9ed1-75d9-9b09-755aea2aac42` |
| `principal` | нет | email или `svc:name` | `andy.krivenko@gmail.com` |
| `request_id` | да | UUIDv4 (уникален на каждый вызов) | автоматически клиентом |
| `correlation_id` | нет | UUID цепочки | опционально |
| `emitted_at` | да | RFC3339 UTC | автоматически клиентом |
### Формат session_id для разных типов
| session_type | session_id | Как получить |
|---|---|---|
| `roo` | Roo session_uid из `history.md` | `H2_SESSION_ID` ENV |
| `perplexity` | slug из URL `perplexity.ai/computer/tasks/<SLUG>` | `H2_SESSION_ID` ENV |
| `owui` | chat_id из OWUI | `H2_SESSION_ID` ENV |
| `cli` | кастомная строка ≤128 символов | явно в вызове |
| `service` | имя сервиса + timestamp | автоматически из hostname |
| `cron` | job_id из cron-планировщика | автоматически |
### Формат product_version (PEP 440 local version)
- Простой: `0.4.0`, `0.4.0.dev1`
- С SHA артефакта: `0.4.0+sha256.3053557e` (для wheel-версий рекомендуется)
- Точки `.` вместо дефисов в SHA-части (PEP 440 нормализует автоматически)
---
## 3. Операции ADB (актуальный список — 0.4.1)
| Операция | Actor обяз. | HMAC обяз. | Read/Write | Wheel |
|---|---|---|---|---|
| `get_document` | нет | нет | R | 0.4.1 |
| `full_state_report` | нет | нет | R | 0.4.1 |
| `list_products_state` | нет | нет | R | 0.4.1 |
| `list_nodes` | нет | нет | R | 0.4.1 |
| `register_document` | shadow-опционально, warn/enforce обяз. | 0.4.2+ | W | 0.4.1 |
| `register_product_state` | shadow-опционально, warn/enforce обяз. | 0.4.2+ | W | 0.4.1 |
| `register_node` | shadow-опционально, warn/enforce обяз. | bootstrap-HMAC 0.4.2+ | W | 0.4.1 |
| `list_caller_events` | да | нет | R | 0.5.0 (не в 0.4.1) |
| `who_touched` | да | нет | R | 0.5.0 (не в 0.4.1) |
**Read-only операции остаются без обязательного actor** — легаси-клиенты и клиенты без credential всегда могут скачать актуальный Гайд.
**Что удалено из v0.8:** операция `include_nodes` в 0.4.1 не поддерживается (возвращает `E_UNKNOWN_OP`). Если она понадобится — вернётся в отдельной wheel.
### 3.1. Формат `applies_to_version_range` (для `register_document`)
Поле принимает **только**:
- Конкретную PEP 440 версию: `0.4.1`, `0.5.0`, `1.0.0.dev1`
- Wildcard: `*` (документ применяется ко всем версиям продукта)
**Не поддерживается** (возвращает `E_BAD_VERSION_RANGE`): `==0.4.1`, `>=0.4.0`, `~=0.4.1`, `>=0.4.1,<0.5`, а также произвольные строки вроде `stage3`.
Upsert идёт по ключу `(env, product, doc_type, applies_to_version_range)` — если хотите держать два отчёта параллельно (например, `stage3-final-0.4.1` и `functional-0.4.1`), назначайте им **разные** `applies_to_version_range` (один — конкретную версию `0.4.1`, второй — `*`).
**Практика для Stage-комплектов документов:** если одна wheel требует несколько `Стандартов` (spec, handoff, PMA), кладите их под разные local-version suffix'ы: `0.4.2` (spec), `0.4.2+handoff`, `0.4.2+pma`. Форматы `0.4.2.post1` и range-операторы отклоняются.
### 3.4. `register_product_state` — полный список required-полей
Операция требует **12 top-level полей**, все обязательны:
| Поле | Тип | Пример |
|---|---|---|
| `env` | string | `prod` \| `staging` \| `dev` |
| `product` | string | `ai_docs_broker` |
| `node` | string | `heavy02` |
| `version` | длинная версия | `0.4.1+sha256.<sha>` |
| `wheel_version` | PEP 440 | `0.4.1` |
| `wheel_sha256` | hex-64 | `…` |
| `wheel_path` | absolute path | `C:/H2/ai_docs_broker/dist/….whl` |
| `state` | string | `deployed` \| `staged` \| `rolled_back` |
| `registered_by` | string | `ai-architect` |
| `install_status` | string | `active` \| `inactive` \| `superseded` |
| `migration_state` | string | `applied` \| `pending` \| `unknown` |
| `updated_by` | string | `ai-architect` |
Опциональные: `previous_version`, `comment`, `applied_migrations` (list), `notes`.
Если хотя бы одно required-поле отсутствует — `E_MISSING_FIELD` с указанием конкретного имени.
### 3.2. Enum `doc_type`
Фактически ADB 0.4.1 принимает **только 7 русских значений**:
- `Гайд Пользователя`
- `Гайд Архитектора`
- `Онтология`
- `Live Scenario`
- `Дорожная Карта`
- `Стандарт`
- `Отчёт Валидации`
Для документов типа «Концепт», «Hand-off», «PMA» — используйте `Стандарт` с уникальным `version` и/или уникальным `applies_to_version_range`.
---
## 4. Ответы broker — новая структура
Все ответы (успех и ошибка) содержат три служебных поля:
```json
{
"ok": true,
"data": {"...результат операции..."},
"actor": { "...эхо actor из запроса..." },
"broker": {
"product": "ai_docs_broker",
"node": "heavy02",
"product_version": "0.4.1+sha256.<wheel>",
"request_id_ack": "<ваш request_id>",
"processed_at": "<RFC3339>"
},
"broker_hints": {
"actor_phase": "enforce",
"hmac_phase": "enforce",
"required_fields": ["product","node","product_version","session_type","session_id","request_id","emitted_at"],
"guide_doc_type": "user_guide",
"guide_hint": "Fetch latest guide via get_document(doc_type='user_guide', product='ai_docs_broker').",
"client_min_version": "0.1.1",
"warnings": []
}
}
```
**`broker_hints` возвращается всегда, даже в успешном ответе, даже для legacy-клиентов.**
Возможные записи `broker_hints.warnings[]` (0.4.3):
| code | reason | action |
|---|---|---|
| `client_too_old` | `client_version < 0.1.1` | обновить client library |
| `must_rotate` | credential с `bootstrap_mode='insecure'` (из fallback 0.4.2) | вызвать `rotate_node_credential` |
| `insecure_deployment` | сервис поднят с `ADB_HMAC_REQUIRE_SECRETS=false` вручную | сообщить оператору |
| `actor_missing_read` | read-op пришёл без actor | добавить actor для аудит-следа |
Клиенты должны при получении ответа:
1. Сравнить свой `client_version` с `broker_hints.client_min_version`. Если ниже — залогировать warning и продолжить.
2. Если `broker_hints.actor_phase = "warn"` и `warnings` содержит `actor_missing` — обновиться срочно.
3. Если `broker_hints.actor_phase = "enforce"` и в ответе `E_ACTOR_MISSING_*` — принудительно обновиться перед следующим вызовом.
---
## 5. Bootstrap: как новый агент получает Гайд без deadlock
**Сценарий:** у вас legacy-агент, не знающий про actor. Вы хотите его обновить, но обновление требует нового Гайда, а Гайд лежит в ADB.
**Решение:** `get_document` навсегда остаётся read-only и **не требует actor**. Legacy-агент может:
```bash
# Прямой вызов через OWUI (без actor, без HMAC):
curl -X POST https://chat.h2platform.ru/api/chat/completions \
-H "Authorization: Bearer $TOKEN" \
-d '{
"model": "h2_ai_docs_broker_function",
"messages": [{
"role": "user",
"content": "```json\n{\"op\":\"get_document\",\"params\":{\"doc_type\":\"user_guide\",\"product\":\"ai_docs_broker\",\"env\":\"prod\"}}\n```"
}]
}'
```
В ответе:
- `data.content_owui_file_id` — скачать через `curl https://chat.h2platform.ru/api/v1/files/<id>/content`
- `broker_hints.guide_hint` — человекочитаемая инструкция что делать дальше
- `broker_hints.required_fields` — список полей, которые надо начать слать в write-операциях
Так любой агент любой версии получает актуальный Гайд и знает, как обновиться. Никакого chicken-and-egg.
---
## 6. Чтение audit log (доступно с 0.4.3)
### 6.1. `list_caller_events` — все вызовы
**Обязательные параметры:** `env`, `product`. **Actor:** обязателен.
```json
{
"op": "list_caller_events",
"actor": {"...ваш actor..."},
"params": {
"env": "prod",
"product": "ai_docs_broker",
"filters": {
"actor_product": "your_product",
"actor_session_type": "roo|perplexity|owui|cli|service|cron|__legacy__",
"op": "register_document",
"hmac_verified": 1,
"bootstrap_mode": "secure|insecure|n/a",
"result_status": "ok|client_error|server_error",
"since": "2026-09-06T00:00:00Z",
"until": "2026-09-07T00:00:00Z"
},
"limit": 1000,
"order": "emitted_at_desc",
"include_payload_hash": false
}
}
```
- Все фильтры опциональны и комбинируются AND.
- Без `since` — окно последних 24 часов.
- `hmac_key_id` возвращается маскированным до 8 символов (`nc_xNtVL5...`).
- `limit ≤ 1000`.
### 6.2. `who_touched` — история конкретного документа/state
Кто последним изменил документ 65:
```json
{
"op": "who_touched",
"actor": {"...ваш actor..."},
"params": {
"env": "prod",
"product": "ai_docs_broker",
"document_id": 65,
"limit": 100
}
}
```
- Альтернатива: `product_state_id` вместо `document_id`.
- Ответ: `data.touches[]` — упорядоченный список write-событий (register/upsert), приведших к текущему состоянию.
- Записи до 0.4.1 (без `request_id`) помечаются `pre_hmac: true`.
- `limit ≤ 100`.
### 6.3. Ротация credential узла
```json
{
"op": "rotate_node_credential",
"actor": {"...ваш actor..."},
"params": {
"env": "prod",
"product": "ai_docs_broker",
"node": "heavy02",
"current_key_id": "nc_xNtVL5ZvDAvqzRIVruZXu",
"grace_window_seconds": 86400,
"reason": "scheduled_rotation|compromised|bootstrap_insecure"
}
}
```
- Ответ: `data.new_credential = {key_id, secret, created_at, expires_at}` — сохраните `secret` немедленно (второй раз он не выдаётся).
- Старый credential получает `revoked_at=NOW()` и принимается только для read в течение `grace_window_seconds` (default 24h).
- Новый credential получает `bootstrap_mode='secure'` — при этом `must_rotate`-warning исчезает.
---
## 7. Фазы rollout — что вам нужно делать
| Фаза | Версия ADB | Что делать |
|---|---|---|
| **A. Shadow** | 0.4.1 | Установить `ai_docs_broker_client`, создать `actor.toml`. Legacy-код продолжит работать. |
| **B. Warn** | 0.4.2 (fallback) | Все write-операции должны идти через client. При legacy write — warning в ответе, но операция проходит. |
| **C. Enforce** | **0.4.3 (текущая цель)** | Все write-операции без actor → `E_ACTOR_REQUIRED`. Клиент `≥0.1.1` без HMAC → `E_HMAC_REQUIRED`. Read-ops без actor — по-прежнему разрешены (fallback для §5). |
| **D. Read enforce** | 0.5.0 (Stage 6) | Read-ops начинают требовать actor. `get_document` для bootstrap остаётся исключением. |
**Read-only операции `get_document` и `full_state_report` не требуют actor до 0.5.0** — это гарантия для legacy-fallback. Аудит-операции `list_caller_events`/`who_touched` требуют actor с 0.4.3 (иначе смысл теряется).
### 7A. Что делать в переходном периоде 0.4.2 → 0.4.3
До релиза 0.4.3 продолжайте работать по Гайду v0.9. Ничего ломать не нужно: 0.4.3 не меняет ни одну сигнатуру существующих операций, только добавляет новые и включает enforce.
---
## 8. Ошибки — что означают
| Код | Как чинить |
|---|---|
| `E_UNKNOWN_OP` | Проверить `op` в payload — сверить со списком §3 |
| `E_MISSING_FIELD` | В `data.message` указано какое поле — добавить в top-level payload |
| `E_BAD_VERSION_RANGE` | `applies_to_version_range` = только конкретная версия (`0.4.1`) или `*` (см. §3.1) |
| `E_INVALID_DOC_TYPE` | `doc_type` должен быть из enum §3.2 |
| `E_ACTOR_MISSING_PRODUCT` | Проверить `~/.h2/actor.toml` |
| `E_ACTOR_MISSING_NODE` | То же |
| `E_ACTOR_MISSING_VERSION` | Указать `product_version` в actor.toml |
| `E_ACTOR_MISSING_SESSION` | Установить ENV `H2_SESSION_TYPE`, `H2_SESSION_ID` |
| `E_ACTOR_MISSING_REQUEST_ID` | Обновить client до 0.1.0+ |
| `E_ACTOR_INVALID_VERSION` | Версия должна соответствовать PEP 440 (`0.1.0` или `0.1.0+sha256.abc`) |
| `E_HMAC_MISSING` | Зарегистрировать node_credential через `register_node` (Stage 4, 0.4.2+) |
| `E_HMAC_INVALID` | Проверить key_id и secret в keyring |
| `E_HMAC_REPLAY` | Проверить NTP на узле — расхождение >±5 минут |
| `E_NODE_REVOKED` | Старый credential ротирован — используйте новый из `rotate_node_credential` |
| `E_ACTOR_REQUIRED` | Enforce-фаза (§7C). Добавьте `actor` в payload write-операции |
| `E_HMAC_REQUIRED` | Enforce-фаза. `client_version ≥ 0.1.1` обязан подписывать write. Обновить keyring |
| `E_MISSING_ADB_KEK` | Сервис 0.4.3 не смог стартовать — оператор должен положить секреты в `.env` |
| `E_INVALID_BOOTSTRAP_SECRET` | Секрет из вашего `.env` не совпадает с серверным. Запросите новый у ИИ-арх |
| `E_INSECURE_BOOTSTRAP` | Сервер в secure-режиме, а `issue_credential` пришёл с insecure secret. Используйте текущий `ADB_BOOTSTRAP_SECRET` |
| `E_CURRENT_KEY_MISMATCH` | `rotate_node_credential` требует, чтобы `current_key_id` совпадал с активным. Сверьте с `list_nodes` |
| `E_ALREADY_ROTATING` | Идёт другая ротация того же узла — подождите grace_window |
В теле каждой ошибки `broker_hints` есть — читайте `hint.guide_hint` для инструкции.
---
## 9. FAQ
**Q: Что если у меня нет client library и я вызываю ADB напрямую через curl/OWUI?**
A: Read-only работает всегда. Для write — нужно вручную собрать actor-объект в payload и HMAC-подпись. Проще установить client.
**Q: Могу ли я использовать ADB без регистрации узла?**
A: Read-only — да (без actor вообще или с любым actor). Write — нет, нужен zarejistrированный node_credential.
**Q: Как ротировать HMAC-secret узла?**
A: `register_node` с параметром `rotate_of=<old_key_id>` создаёт новый credential, старый остаётся валидным 24 часа.
**Q: Что если broker недоступен?**
A: Client library кеширует последний успешный `broker_hints` и `get_document`-ответы на 1 час. Write-операции при недоступности → error, retry с exponential backoff.
**Q: Нужно ли передавать `session_url`?**
A: Нет, поле убрано из v0.2. URL вычислим на клиенте из `(session_type, session_id)`.
---
## 9.1. Про CI-нормализацию имён (важно)
ADB нормализует `product` и `env` через `LOWER()` при поиске совпадения для апсерта. Это значит:
- Разные регистры считаются одним продуктом: `ai_docs_broker`, `ai_Docs_broker`, `AI_DOCS_BROKER` — все матчатся друг с другом.
- Тестовые прогоны на «throwaway» продукте всегда должны использовать имя, отличающееся не только регистром, а корнем: `func_test_throwaway_<uuid>` — иначе можно случайно апсертнуть чужой документ.
Всегда используйте snake_case и уникальный корень для тестовых имён.
---
## 11. Retention caller_events (0.4.3)
- Cron-скрипт `_ops/cleanup_caller_events.py` на heavy02 удаляет записи `caller_events` старше 30 суток.
- Расписание: ежедневно в 03:00 UTC (systemd/cron unit ставится оператором вручную в 0.4.3; автоматизация — в 0.5.0).
- Отчёт удаления: `_ops/cleanup_reports/caller_events_YYYYMMDD.json`.
- Если вам нужны более старые записи для расследования — экспортируйте до 30-дневного окна.
---
## 10. Куда обращаться
- Актуальный Гайд: `get_document(doc_type='user_guide', product='ai_docs_broker', env='prod')`
- Онтология (для разработчиков): `get_document(doc_type='ontology', product='ai_docs_broker', env='prod')`
- Дорожная карта: `get_document(doc_type='roadmap', product='ai_docs_broker', env='prod')`
- Live scenario (что работает end-to-end): `get_document(doc_type='live_scenario', product='ai_docs_broker', env='prod')`
- Bootstrap secret и вопросы: ИИ-архитектор H2 через OWUI.
### Исходная версия v0.7 (doc_id=231)
# Гайд Пользователя ai_Docs_broker (v0.7)
**Продукт:** `ai_Docs_broker` — сервис-реестр документации продуктов H2 (Гайды, Онтологии, Live Scenario, Дорожные карты, Стандарты, Отчёты Валидации), с wheel 0.4.0 — также реестр узлов флота H2.
**Дата:** 2026-09-05. **Живой брокер:** wheel 0.4.0 (выкат 2026-09-05 20:26 UTC на HEAVY02, LS v0.4 17/17 GREEN). **Узел с сервисом:** HEAVY02.
**Первичный вход для ИИ-архитектора:** OWUI Function `h2_ai_docs_broker_function` через POST `https://chat.h2platform.ru/api/chat/completions`.
> **Изменения v0.6 → v0.7 (2026-09-05):** wheel 0.4.0 — добавлены три раздела о реестре узлов флота:
> `§3.5 register_node`, `§3.6 list_nodes`, `§3.7 full_state_report(include_nodes=true)`. KNOWN_OPS в §3 расширен с 5 до
> **7 живых операций**. Новый блокирующий контракт `register_product_state`: узел должен быть зарегистрирован в `nodes` до
> первого `register_product_state(node=...)` — иначе `E_NODE_NOT_REGISTERED` (§5). Обновлены §5 (коды
> `E_NODE_NOT_REGISTERED`, `E_BAD_NODE_CLASS`, `E_BAD_NODE_STATUS`), §6.
>
> **Изменения v0.4 → v0.5 (2026-09-05):** enum `doc_type` расширен с 5 до **7**
> значений — добавлены `Стандарт` и `Отчёт Валидации` (Этап 0 Дорожной Карты
> AVAL Universalization v11; миграция `002_doc_type_enum_v2.sql`). Обновлены
> §3.1 (список doc_type), §3.4 (валидация enum), §5 (`E_BAD_DOC_TYPE`),
> §Ограничения. Новый §6.1 — когда регистрировать `Стандарт` vs `Отчёт
> Валидации`.
---
## §1. Кто пользуется брокером и через что
| Роль | Инструмент | Транспорт |
|---|---|---|
| Оператор | OWUI-чат вручную | `POST /api/chat/completions`, model=`h2_ai_docs_broker_function` |
| ИИ-архитектор | OWUI-чат из бота или из своего скрипта | `POST /api/chat/completions`, model=`h2_ai_docs_broker_function` |
| ИИ-кодер / сервис на узле | NATS-клиент внутри Ring 0 | `NATS request` на subject `h2.ai_docs_broker.request` |
Оператор и ИИ-архитектор **не имеют прямого NATS**. Всегда через OWUI Function. Function сама оборачивает плоский `op` в nested envelope wheel и делает `nc.request()` к сервису.
---
## §2. Общий контракт вызова через OWUI Function
**Endpoint:** `POST https://chat.h2platform.ru/api/chat/completions`
**Заголовок:** `Content-Type: application/json`, `Authorization: Bearer <OWUI_TOKEN>`.
**Тело:**
```json
{
"model": "h2_ai_docs_broker_function",
"stream": false,
"messages": [
{"role": "user", "content": "```json\n<PAYLOAD>\n```"}
]
}
```
где `<PAYLOAD>` — JSON с обязательным полем `op` и плоскими параметрами (Function сама соберёт nested envelope).
**Ответ:** SSE-поток кадров `data: {...}`. Финальный кадр содержит `h2_meta.status="ok"` и `h2_meta.elapsed_ms=<int>`. Полезная нагрузка приходит в теле кадра `⇠ reply:` внутри `content`.
**Латентность нормы:** 20–500 мс на узле HEAVY02.
---
## §3. Операции
Живой KNOWN_OPS (wheel 0.4.0, проверено Live Scenario v0.4 2026-09-05) — **семь** операций:
1. `get_document` — получить активную запись по (env, product, doc_type).
2. `register_document` — зарегистрировать документ (upsert по ключу, старая активная — в архив).
3. `full_state_report` — весь реестр (с фильтрами; в wheel 0.4.0 — также опц. `include_nodes`).
4. `list_products_state` — таблица состояния продуктов (где какой wheel развёрнут).
5. `register_product_state` — записать состояние развёртывания продукта на узле (требует с wheel 0.4.0, чтобы `node` уже был в `nodes`).
6. **`register_node`** (новое в wheel 0.4.0) — зарегистрировать узел во флоте (upsert, archive-then-update).
7. **`list_nodes`** (новое в wheel 0.4.0) — перечислить узлы флота с фильтрами `class`/`status`.
**Чего в брокере НЕТ** (выдаёт `E_UNSUPPORTED_OPERATION`, evidence 2026-09-04): `upload_file`, `echo`, `health`, `list_documents`, `search_documents`. Загрузка файла в OWUI Files — **прямой multipart POST**, мимо Function (см. §3.3).
### §3.1. `get_document` — получить документ по (env, product, doc_type)
Возвращает активную (не архивную) запись реестра с `owui_file_id` и `sha256`.
**PAYLOAD:**
```json
{"op":"get_document","env":"prod","product":"H2","doc_type":"Гайд Архитектора"}
```
**Reply.data.row** содержит:
- `id` — числовой идентификатор записи реестра
- `env` — `dev` \| `test` \| `prod`
- `product` — имя продукта
- `doc_type` — `Гайд Пользователя` \| `Гайд Архитектора` \| `Онтология` \| `Live Scenario` \| `Дорожная Карта` \| `Стандарт` \| `Отчёт Валидации`
- `version` — строка версии
- `owui_file_id` — UUID файла в OWUI Files
- `filename` — имя файла в OWUI Files
- `sha256` — контрольная сумма
- `uploaded_at` — ISO-8601 UTC
- `uploaded_by` — идентификатор загрузившего
- `comment` — краткое описание версии
Если документа нет: `data.present=false`.
### §3.2. `full_state_report` — весь реестр
**PAYLOAD:**
```json
{"op":"full_state_report"}
```
Опциональные фильтры: `env`, `product`, `doc_type`, `include_archives` (default true), `include_products_state` (default true).
Возвращает: `data.counts`, `data.documents`, `data.documents_archive`, `data.products_state`, `data.schema_meta` (перечисления `env` и `doc_type`).
### §3.3. Загрузка файла — прямой multipart POST в OWUI Files
**Операции `upload_file` через Function НЕТ** (`E_UNSUPPORTED_OPERATION` в брокере `h2_ver=0.1.0`). Файлы загружаются **напрямую** в OWUI Files API:
**Endpoint:** `POST https://chat.h2platform.ru/api/v1/files/`
**Content-Type:** `multipart/form-data`
**Заголовок:** `Authorization: Bearer <OWUI_TOKEN>` (тот же токен).
**Поле формы:** `file=@<путь>;type=text/markdown`
**Пример:**
```bash
curl -X POST "https://chat.h2platform.ru/api/v1/files/" \
-H "Authorization: Bearer $OWUI_TOKEN" \
-F "file=@GUIDE_HOW_TO_CREATE_H2_PRODUCT_v0_12.md;type=text/markdown"
```
**Ответ (JSON, не SSE):**
```json
{
"id": "7193c61f-eefa-4e39-9d06-09d21c48b411",
"filename": "GUIDE_HOW_TO_CREATE_H2_PRODUCT_v0_12.md",
"meta": {
"size": 137883,
"file_hash": "636a92b824ec150210289d04e3d0943cd9b6c828607f7caedd1b4665285e7ecc"
}
}
```
**Соответствие полей для последующего `register_document`:**
| Ответ OWUI Files | Поле `register_document` |
|---|---|
| `id` | `owui_file_id` |
| `filename` | `filename` |
| `meta.file_hash` | `sha256` |
| `meta.size` | `size` |
**Границы:** нет лимита SSE-кадра (в отличие от удалённого `upload_file`); крупные файлы (>5 МБ) — тот же канал.
### §3.4. `register_document` — зарегистрировать новую версию
Регистрирует запись в реестре и **автоматически архивирует** прежнюю активную запись с тем же ключом `(env, product, doc_type)`.
**PAYLOAD (обязательные поля, живой брокер `h2_ver=0.1.0`):**
```json
{
"op": "register_document",
"env": "prod",
"product": "H2",
"doc_type": "Гайд Архитектора",
"version": "0.12",
"owui_file_id": "7193c61f-eefa-4e39-9d06-09d21c48b411",
"filename": "GUIDE_HOW_TO_CREATE_H2_PRODUCT_v0_12.md",
"sha256": "636a92b824ec150210289d04e3d0943cd9b6c828607f7caedd1b4665285e7ecc",
"size": 137883,
"uploaded_by": "ai-architect",
"comment": "v0.12: §G.core P5..P16 + check 10q"
}
```
**Обязательные поля — живой брокер отвечает `E_MISSING_FIELD` на отсутствие любого:**
1. `op = "register_document"`
2. `env` — валидация ∈ {`dev`, `test`, `prod`}
3. `product`
4. `doc_type` — ровно 7 значений (§3.1), любое другое — `E_BAD_DOC_TYPE`
5. `version`
6. `owui_file_id` — возвращён прямым multipart POST (§3.3, поле `id`)
7. `filename` — имя файла в OWUI Files (поле `filename`)
8. `sha256` — контрольная сумма (поле `meta.file_hash`); сервер сверяет с реальным файлом по `owui_file_id` — `E_SHA_MISMATCH` при расхождении
9. `size` — размер в байтах (поле `meta.size`)
10. `uploaded_by` — идентификатор загрузившего (не `author`)
**Необязательно:** `title`, `comment`, `notes`, `task_id` (для replay-cache).
**Reply.data:**
- `registered.id` — id новой записи в `documents`
- `archived_id` — id старой записи, перенесённой в `documents_archive` (или `null`, если ключ был новым)
- `owui_file_id`, `version` — echo
### §3.5. `register_node` — зарегистрировать узел флота (wheel 0.4.0)
С wheel 0.4.0 введён реестр узлов флота H2 в таблице `nodes`. До первого `register_product_state(node=<X>)` узел `<X>` должен быть зарегистрирован.
**PAYLOAD (обязательные поля):**
```json
{
"op": "register_node",
"node_id": "heavy01",
"class": "heavy",
"purpose": "Резервный/зеркальный GPU-узел; будущий второй prod-узел ai_Docs_broker",
"registered_by": "architect@h2"
}
```
**Опциональные поля:**
- `status` — одно из `active` \| `planned` \| `retired`. По умолчанию в wheel 0.4.0 — `planned`. Перевод `planned → active` происходит автоматически при первом успешном `register_product_state` для узла.
- `comment` — свободная строка.
**Валидация:**
| Код | Условие |
|---|---|
| `E_MISSING_FIELD` | Отсутствует `node_id` / `class` / `purpose` / `registered_by` (или значение пустое) |
| `E_BAD_NODE_CLASS` | `class` вне enum `{heavy, light, laptop}` |
| `E_BAD_NODE_STATUS` | `status` вне enum `{active, planned, retired}` |
**Семантика:** archive-then-update-in-place. Первый вызов для `node_id` — INSERT (`created=true`, `archive_id=null`). Повторный — предыдущая актуальная строка уходит в `nodes_archive` с `archive_reason='update'`, актуальная заменяется UPDATE-ом (`updated=true`, `archive_id=<int>`).
**Reply.data:**
```json
{
"created": true,
"updated": false,
"new_id": 3,
"archive_id": null,
"node": {
"node_id": "heavy01",
"class": "heavy",
"status": "planned",
"purpose": "...",
"registered_at": "2026-09-05T20:29:12.418Z",
"registered_by": "architect@h2"
}
}
```
### §3.6. `list_nodes` — перечислить узлы флота (wheel 0.4.0)
Read-only. Возвращает все актуальные строки `nodes`, опционально с фильтрами.
**PAYLOAD (базовый):**
```json
{"op":"list_nodes"}
```
**Опциональные фильтры:**
- `class` — `heavy` \| `light` \| `laptop`
- `status` — `active` \| `planned` \| `retired`
- `include_archives` — bool, default `false`. Если `true` — дополнительно возвращает срез `nodes_archive` с теми же фильтрами.
Фильтры — конъюнкция (`AND`).
**Reply.data:**
```json
{
"nodes": [
{"node_id":"heavy02","class":"heavy","status":"active","purpose":"...","registered_at":"...","registered_by":"architect@h2","updated_at":"..."},
...
],
"counts": {"nodes": 6, "nodes_archive": 0}
}
```
### §3.7. `full_state_report(include_nodes=true)` — единый отчёт (wheel 0.4.0)
С wheel 0.4.0 у `full_state_report` появился флаг `include_nodes` (default `false` — бэквард-совместимость).
**PAYLOAD:**
```json
{"op":"full_state_report","include_nodes":true}
```
**Что меняется в ответе при `include_nodes=true`:**
- в `data` появляется ключ `nodes` (тот же формат, что в `list_nodes.data.nodes`);
- в `data.counts` появляется `nodes: N`.
Без флага (default) в ответе ключа `nodes` НЕТ — клиенты wheel 0.2.0/0.3.0 не сломаются (проверено LS v0.4 шаг 16).
---
## §4. Полный сценарий регистрации новой версии Гайда
**Два HTTP-вызова (без `upload_file`, его в живом брокере нет):**
**1. Прямой multipart POST в OWUI Files** (возвращает `id`, `filename`, `meta.file_hash`, `meta.size`):
```bash
RESP=$(curl -sS -X POST "https://chat.h2platform.ru/api/v1/files/" \
-H "Authorization: Bearer $OWUI_TOKEN" \
-F "file=@$FILE;type=text/markdown")
OWUI_FILE_ID=$(echo "$RESP" | jq -r .id)
SHA=$(echo "$RESP" | jq -r .meta.file_hash)
SIZE=$(echo "$RESP" | jq -r .meta.size)
```
**2. `register_document` через OWUI Function** с полученными метаданными (все 10 обязательных полей). Прежняя активная запись автоматически архивируется (upsert по `(env, product, doc_type)`).
**3. `get_document`** (верификация) — убедиться, что реестр вернул нужный `owui_file_id` и `version`; sha256 сверен.
Готовый bash-скрипт — в §5 Гайда ИИ-архитектора H2 (два вызова: multipart POST + `register_document`).
---
## §5. Ошибки и их значения
| Код в reply | Причина | Что делать |
|---|---|---|
| `E_UNSUPPORTED_OPERATION` | `op` не в живом KNOWN_OPS (5 операций — §3). Типично: `upload_file`, `echo`, `health` — их нет в `h2_ver=0.1.0` | Заменить канал (для загрузки — прямой multipart POST, §3.3); `echo`/`health` убрать из probe |
| `E_MISSING_FIELD` | Нет обязательного поля в payload. Сообщение: `missing required field: <name>` | См. §3.4 (10 обязательных полей для `register_document`); включая `filename`, `sha256`, `size`, не только `owui_file_id` |
| `E_BAD_DOC_TYPE` | `doc_type` вне enum (7 значений). Типично: `Концепт`, `PMA`, англоязычные лейблы | L1 Концепт регистрировать как `Гайд Архитектора` (канон h2_openbrowser); PMA — внутрь Live Scenario без отдельной записи |
| `E_SHA_MISMATCH` | sha256 в payload не совпадает с реальной суммой файла (сервер сверяет по `owui_file_id`) | Взять `meta.file_hash` из ответа multipart POST, не считать локально |
| `E_NOT_FOUND` | Файла с таким `owui_file_id` нет в OWUI Files | Проверить, что multipart POST вернул `id` со статусом 200 |
| `E_TEMPLATE_UNRESOLVED` | В payload остался литерал-шаблон (`<uuid4>`, `<TASK_ID>`) — мостом отклонён до broker'а | Подставить реальные значения; или ZWSP-обфускация литерала (§F Гайда H2) |
| `E_NO_REPLY` | Сервис-worker не отвечает за timeout (5s) | Проверить статус сервиса на HEAVY02; если down — эскалация Оператору |
| `E_NODE_NOT_REGISTERED` ³ | `register_product_state(node=<X>)` вызван, но `<X>` нет в `nodes` (wheel 0.4.0) | Сначала `register_node(node_id=<X>, class=..., purpose=..., registered_by=...)` (§3.5), затем повтор `register_product_state` |
| `E_BAD_NODE_CLASS` ³ | `register_node.class` вне enum `{heavy, light, laptop}` | Исправить `class` в payload |
| `E_BAD_NODE_STATUS` ³ | `register_node.status` вне enum `{active, planned, retired}` | Исправить `status` в payload |
³ — коды введены в wheel 0.4.0 вместе с `register_node`/`list_nodes` и таблицей `nodes` (миграция `004_nodes_v1.sql`, applied 2026-09-05).
**Латентности выше 5 сек — аномалия.** Норма — 20–500 мс (elapsed_ms в h2_meta).
---
## §6. Инварианты и правила
- **Прямой NATS запрещён Оператору и ИИ-архитектору.** Единственный вход — OWUI Function.
- **`uploaded_by` обязателен** (wheel 0.2.0). Ключ `author` больше не принимается.
- **Автоархив:** `register_document` архивирует прежнюю активную запись с тем же ключом. Ручное удаление не требуется.
- **UPSERT по ключу** `(env, product, doc_type)` — активная запись всегда одна.
- **Sha256 сверяется на сервере** — нельзя зарегистрировать `owui_file_id`, чью sha256 клиент указал неверно.
- **Порядок регистрации узла (wheel 0.4.0):** перед первым `register_product_state(node=<X>)` обязательно вызвать `register_node(node_id=<X>, class, purpose, registered_by)`, иначе `E_NODE_NOT_REGISTERED`. Первый успешный `register_product_state` автоматически переводит узел `planned → active`.
---
## §6.1. Когда регистрировать `Стандарт` vs `Отчёт Валидации` (новое в v0.5)
С добавлением двух doc_type важно не путать их назначение:
| doc_type | Что регистрируется | Пример | Как часто обновляется |
|---|---|---|---|
| `Стандарт` | **Нормативный документ правил/инвариантов** — долгоживущий контракт, на который ссылаются код и прогоны | `STANDARD_UNIVERSAL_RULE_KIT_v1_ai_validation.md` (ai_validation, v1); 4 стандарта H2 | Редко (при изменении правил/контракта) |
| `Отчёт Валидации` | **Результат конкретного прогона валидации** — факт с вердиктом, findings, evidence | `OTCHET_VALIDATION_h2_openbrowser_v0_3_4.md` (h2_openbrowser, v1) | При каждом терминальном прогоне (UPSERT по `(env, product, doc_type)`) |
Правила выбора:
1. **Стандарт** — продукт декларирует обязательные правила для себя или для
валидаторов (`Universal Rule Kit` для `ai_validation` /
`ai_h2_shared_validation`; «как создавать H2-продукт» для `H2`). Регистрирует
владелец норматива (обычно ИИ-архитектор или кодер продукта-эталона).
2. **Отчёт Валидации** — после каждого прогона AVAL/валидатора на продукте
(verdict PASS или BLOCK — оба регистрируются). Регистрирует тот, кто гонял
прогон (`uploaded_by=ai-coder@heavy02` в примерах Этапа C).
3. Один и тот же продукт может иметь оба doc_type одновременно: `Стандарт` —
его правила, `Отчёт Валидации` — последний прогон по этим правилам.
4. Отчёт Валидации не является нормативом; на него ссылаются как на evidence
факта, а не как на источник правил.
---
## §8. Как ИИ-архитектор ведёт задачу заказчика от запроса до приёмки (новое в v0.6)
Этот раздел — **единственный источник процедуры** ведения задачи для любого ИИ-архитектора, использующего ADB. Гайд Архитектора ADB (§14) фиксирует обязательность этой процедуры. Дорожная Карта любого продукта H2 ссылается на этот раздел, не дублируя его.
### §8.1. Общие понятия
- **PMA** — задание другому ИИ-агенту H2 (ИИ-кодеру своего продукта или ИИ-архитектору другого продукта, если задача требует изменений чужого продукта). Не путать с `Отчёт Валидации` — тот фиксирует входящий результат прогона, а PMA — исходящее задание.
- **Адресат PMA** — ИИ-агент, которому ставится задача. У каждого ИИ-агента H2 есть свой Гайд — его нужно прочитать до формулирования PMA.
- **Гайд моста связи** — отдельный документ продукта-моста (например, OWUI–Roo Bridge для связи с ИИ-кодерами). Читается до отправки PMA.
- **Приёмка** — фиксация результата как принятого. Обязательная часть приёмки — только регистрация изменённых документов в ADB. `Live Scenario` и `Отчёт Валидации` — опциональны, см. §8.5.
### §8.2. Восемь шагов
**Шаг 1. Принять запрос заказчика.** Запрос может быть коротким или развёрнутым. Задача шага — зафиксировать продукт, в котором будут изменения, и общее направление.
**Шаг 2. Проверить Дорожную Карту продукта в ADB.**
- Если есть — скачать (`get_document(env=prod, product=<X>, doc_type='Дорожная Карта')`), найти актуальный не-выполненный пункт.
- Если нет — создать новую Дорожную Карту (`doc_type=Дорожная Карта`, env=prod, v0.1) с иерархией этапов. Жесткого шаблона нет; обязательны: краткий обзор версий одной строкой и статусы, пошаговые описания каждого этапа.
**Шаг 3. Определить адресата PMA и затронутые документы.**
- Кто адресат: ИИ-кодер этого продукта (обычный случай) или ИИ-архитектор другого продукта, если задача требует менять чужой продукт.
- Затронутые документы: перечислить, какие документы в ADB будут обновлены (Онтология, Гайд Пользователя, Live Scenario, Стандарт, Дорожная Карта) — своего продукта и чужих, если задеваются.
**Шаг 4. Прочитать Гайд адресата и Гайд моста связи.**
- Гайд адресата — `get_document(env=prod, product=<адресат>, doc_type='Гайд Пользователя')`. Без него PMA невозможно сформулировать корректно.
- Гайд моста — документ продукта-моста (OWUI–Roo Bridge для ИИ-кодеров; аналоги для арх↔арх — по продукту адресата). Описывает контракт отправки, мониторинга, коды ошибок. Если Гайда моста нет в реестре — явно зафиксировать это в PMA как известное ограничение.
**Шаг 5. Проработать все изменения и сформулировать PMA.**
- Конкретизировать все изменения: миграции БД, API-расширения, коды ошибок, обходы регрессий, текстовые правки документов.
- На этом шаге ИИ-архитектор **явно решает**, требуется ли прогон Live Scenario и/или валидации (см. §8.5). Решение и обоснование включаются в PMA.
- PMA регистрируется в ADB как `doc_type=Стандарт`, env=prod, `version=stageN-spec-<wheel>` — спецификация этапа; отдельно hand-off `doc_type=Стандарт`, env=dev, `version=stageN-handoff-<wheel>` — в терминах адресата.
**Шаг 6. Зарегистрировать все подготовленные артефакты в ADB.**
- Обновлённые Онтологии/Гайды продукта (если меняются).
- Спецификация этапа и hand-off из шага 5.
- Live Scenario в dev с новыми шагами приёмки (если выбрана опция его прогона).
- Всё через `register_document`; каждая регистрация возвращает `correlation_id` — фиксировать в evidence.
**Шаг 7. Передать PMA адресату и постоянно проверять, что он верно понял.**
- Отправка — по Гайду моста (для ИИ-кодеров через OWUI–Roo Bridge, с уникальным `TASK_ID`).
- Мониторинг состояния адресата — ежеминутный; глубокая выгрузка истории — каждые ~5 минут.
- При уходе адресата в аналитическую петлю или не туда — вмешаться новым заданием через тот же мост (новый `TASK_ID`, если мост требует его уникальности).
- Принять только при явном завершении адресата (attempt_completion) и совпадении результата с PMA.
**Шаг 8. Зарегистрировать финальные изменения.**
- Обязательно: обновить `products_state` через `register_product_state` (если менялась версия wheel или состояние узла); обновить Дорожную Карту (bump версии, отметить этап ✅).
- Опционально: промотировать Live Scenario из dev в prod, если он вводился; зарегистрировать Отчёт Валидации с `parent_doc_id=<id Дорожной Карты>`, `review_status='выполнен'`, `applies_to_version_range='=<wheel>'`.
### §8.3. Гейт закрытия этапа (минимальный)
Переход считается закрытым, когда в реестре появились **три обязательные записи**:
1. Все изменённые документы продукта (Онтология/Гайды) — upsert.
2. `Дорожная Карта` — bump `v0.M → v0.(M+1)` с отметкой выполненного этапа.
3. `products_state` — актуальная версия wheel/узла.
Записи `Live Scenario` в prod и `Отчёт Валидации` — опциональные (см. §8.5).
### §8.4. Правило именования версий документов этапа
- Спецификация этапа: `stageN-spec-<wheel>` (`env=prod`).
- Hand-off адресату: `stageN-handoff-<wheel>` (`env=dev`).
- Отчёт Валидации (если прогонялся): `stageN-pma-<wheel>` (`env=prod`).
- Live Scenario draft: `<wheel-minor>-draft` (`env=dev`), после промота — `<wheel-minor>` (`env=prod`).
### §8.5. Когда прогонять Live Scenario и валидацию, а когда пропускать
Решение принимает ИИ-архитектор на шаге 5 и явно фиксирует в PMA.
**Прогон Live Scenario требуется, если** в этапе есть хотя бы одно из: миграция схемы БД; новая операция API; изменение контракта существующей операции; новые коды ошибок; изменение поведения runtime; minor/major bump wheel.
**Прогон Live Scenario пропускается, если** все изменения ограничены: правка текста документов (Онтология/Гайд без изменения контракта); patch bump wheel без изменения API; обновление комментариев в записях реестра; косметика в документации.
**Прогон валидации** (Universal Rule Kit / протокол валидации продукта) — отдельное решение от Live Scenario. Прогоняется, если для продукта определён протокол валидации и изменения этапа в его области (например, касаются инвариантов h2_shared).
### §8.6. Инварианты процедуры
- Шаги 1–8 не переставляются и не пропускаются. Пропуск шага 4 (Гайд адресата и моста) — самый частый источник ошибок в hand-off.
- Все документы этапа регистрируются в ADB как единственный источник правды. Локальные копии не заменяют регистрацию.
- Обходы регрессий в чужих продуктах фиксируются явно в PMA и порождают отдельную нормативную задачу адресованную владельцу этого продукта.
- Отсутствие Гайда моста или Гайда адресата в реестре — не блокер, но обязанность их создать перекладывается на владельца соответствующего продукта (через отдельный PMA).
---
## §7. Changelog и известные ограничения (техдолг)
### Changelog
- **v0.7 (2026-09-05)** — wheel 0.4.0 выкачен на HEAVY02 (Live Scenario v0.4 GREEN 17/17):
- §3: KNOWN_OPS расширен с 5 до **7 живых операций** — добавлены `register_node`, `list_nodes`.
- §3.5 (новый): `register_node` — полный контракт, enum классов и статусов, archive-then-update, авто-перевод planned→active при первом `register_product_state`.
- §3.6 (новый): `list_nodes` — read-only с фильтрами `class`/`status`/`include_archives`.
- §3.7 (новый): `full_state_report(include_nodes=true)` — единый отчёт + BC без флага.
- §5: три новых кода ошибок — `E_NODE_NOT_REGISTERED`, `E_BAD_NODE_CLASS`, `E_BAD_NODE_STATUS`.
- §6: добавлен инвариант об обязательном порядке `register_node` → `register_product_state`.
- **v0.6 (2026-09-05)** — добавлен §8 (процессная область):
- **§8 (новый)**: полная восьмишаговая процедура ведения задачи заказчика от запроса до приёмки; PMA определён как **задание адресату** (ИИ-кодеру своего продукта или ИИ-арху чужого продукта); обязательное чтение Гайда адресата и Гайда моста связи на шаге 4.
- **§8.3 гейт закрытия**: минимальный гейт — 3 обязательные записи (документы продукта, Дорожная Карта, `products_state`). Live Scenario и Отчёт Валидации — опциональны (§8.5).
- **§8.5 опциональность приёмки**: критерии, когда прогонять Live Scenario и валидацию и когда пропускать.
- **§8.4 именование версий**: канон `stageN-spec-*`, `stageN-handoff-*`, `stageN-pma-*` — выведен из фактического хода этапа 1.
- **v0.5 (2026-09-05)** — enum `doc_type` расширен до 7 значений (Этап 0 v11):
- §3.1 и §3.4: список doc_type и валидация enum — 7 значений (добавлены `Стандарт`, `Отчёт Валидации`).
- §5: `E_BAD_DOC_TYPE` — enum из 7 значений.
- §6.1 (новый): когда регистрировать `Стандарт` vs `Отчёт Валидации`.
- Ограничения: enum описан как семизначный.
- **v0.4 (2026-09-04)** — evidence-baseline к `h2_ver=0.1.0`:
- §3 KNOWN_OPS: список сведён к 5 живым операциям; `upload_file`, `echo`, `health`, `list_documents`, `search_documents` отмечены как `E_UNSUPPORTED_OPERATION`.
- §3.3: канал загрузки переписан на прямой multipart POST в OWUI Files API; таблица соответствия полей.
- §3.4: список обязательных полей расширен до 10 (добавлен `size`; `filename` и `sha256` вынесены явно).
- §4: сценарий переписан — два вызова (multipart POST + register_document) вместо трёх.
- §5: добавлены коды `E_UNSUPPORTED_OPERATION`, `E_MISSING_FIELD`, `E_BAD_DOC_TYPE`, `E_TEMPLATE_UNRESOLVED`.
- **Обратная совместимость:** код v0.3, вызывающий `upload_file` внутри Function, будет получать `E_UNSUPPORTED_OPERATION` и должен быть переписан на прямой multipart POST.
- **v0.3 (2026-09-03)** — первая версия Гайда, не подтвержденная evidence-baseline живого брокера.
- **v0.2** — архив, была в dev.
### Ограничения
- `doc_type` enum ограничен семью значениями (`Гайд Пользователя`, `Гайд Архитектора`, `Онтология`, `Live Scenario`, `Дорожная Карта`, `Стандарт`, `Отчёт Валидации`). L1 Концепт продукта регистрируется как `Гайд Архитектора` (канон донора `h2_openbrowser`), маркер уровня — в префиксе filename `L1_CONCEPT_`. PMA в enum отсутствует и не регистрируется (живёт внутри Live Scenario).
- Прямой multipart POST в OWUI Files — единственный канал загрузки; лимит SSE-кадра не применим.
- Symphonic UUIDv5 marker'ы (генерируются, когда реальный `owui_file_id` не указан при регистрации) не скачиваются — GET /content возвращает 404. Это баг брокера: должен отклонять регистрацию с synthetic id.
---
**Актуальная версия:** v0.7. Предыдущая: v0.6 (prod, id=57 в ADB). Автор: ИИ-архитектор + ai-coder@heavy02 (Roo). Evidence: wheel 0.4.0 (sha256 `3053557e0085ad1eba244f0c777878366cda6a0fc06500181b90f42d07008c16`), Live Scenario v0.4 GREEN 17/17 (2026-09-05 20:35, evidence OWUI `fd3eea24-96a2-4506-b362-d0ecb0dad104`), 6 `register_node` correlation_id зафиксированы в PMA `stage2-pma-0.4.0`.
### Исходная версия v0.26 (doc_id=414)
# ADB Гайд Пользователя v0.26
**Дата:** 2026-09-13
**Продукт:** ai_docs_broker
**Prod:** 0.9.0a6
**Родитель:** v0.25 (doc_id=414)
## Что нового в v0.26 (кумулятивно к v0.25)
- **§36 NEW** — «Как регистрировать документ: правило имени продукта».
- Разделы §0..§35 v0.25 сохранены.
---
## §36. Имя продукта — только `lower_snake_case`
В разделе «Как регистрировать документ» действует единое правило.
> **Внимание:** имя продукта — только в `lower_snake_case`
> (`^[a-z][a-z0-9_]*$`). Заглавные буквы, дефисы, пробелы → `E_INVALID_PRODUCT_NAME`.
**Валидные примеры:** `ai_docs_broker`, `owui_roo_bridge`, `h2_shared`.
**Невалидные примеры:** `Ai_Docs_broker` (заглавные), `ai-docs-broker`
(дефисы), `1ai_broker` (начинается с цифры), `ai docs broker` (пробелы).
Правило действует для операций `register_document`, `register_product` и
`bulk_deprecate_documents`. Подробное обоснование — Онтология v0.18 §2.1,
Гайд Архитектора v0.13 §32.
**Почему:** раньше регистр не нормализовался, и это приводило к путанице —
запись `ai_Docs_broker` считалась той же, что `ai_docs_broker`, что вызывало
ошибки при массовых операциях. Теперь на входе гейт отвергает неверный регистр
сразу (`E_INVALID_PRODUCT_NAME`), а на уровне БД колонки сравняются
байт-в-байт (`utf8mb4_bin`).
## Унаследовано из v0.25 (кумулятивно)
- §31 — Runtime map (`product_runtime_map`).
- §32 — Регистрация wheel (обязательный шаг деплоя).
- §33 — Читаем drift (`products_state` vs `active_deploys`).
- §34 — Список op'ов (49 + 4).
- §35 — Enum-ловушки `products_state.state`.
§END v0.26
### Исходная версия v0.27 (doc_id=483)
# ADB Гайд Пользователя v0.27
Delta vs v0.26. Остальное — без изменений.
## §11-NEW. Управление типами документов
Начиная с broker 0.9.0a8, `doc_type` — не жёстко зашитый enum, а управляемый реестр `doc_types`. Пользователь может завести свой тип документа без релиза брокера.
### 11.1. Зарегистрировать новый doc_type
**Op:** `register_doc_type` (WRITE, HMAC HARD)
**Payload:**
```json
{
"op": "register_doc_type",
"env": "prod",
"name": "Реестр Изменений",
"description": "Список изменений между версиями продукта (changelog)",
"actor": { ... }
}
```
**Правила имени:** регекс `^[A-ZА-Я][A-ZА-Яa-zа-я0-9_ \-]{1,63}$`. Регистр значим. Разрешены кириллица, латиница, цифры, пробел, дефис, подчёркивание. Первый символ — буква в верхнем регистре.
**Успех:** `{"status":"ok", "data":{"new_id":<int>, "env":"prod", "name":"...", "description":"..."}}`
**Ошибки:**
- `E_INVALID_DOC_TYPE` — имя не проходит регекс.
- `E_DOC_TYPE_EXISTS` — уже зарегистрирован в этом env.
- `E_HMAC_REQUIRED` — write без HMAC.
### 11.2. Посмотреть список доступных doc_type
**Op:** `list_doc_types` (READ)
**Payload:**
```json
{
"op": "list_doc_types",
"env": "prod",
"include_deprecated": false
}
```
**Ответ:**
```json
{
"status": "ok",
"data": {
"doc_types": [
{"name":"Гайд Пользователя", "description":null, "added_by":"system:seed-031", "created_at":"...", "deprecated":false, "in_use_count":22},
{"name":"Реестр Изменений", "description":"Changelog...", "added_by":"andy.krivenko@gmail.com", "created_at":"...", "deprecated":false, "in_use_count":0}
]
}
}
```
### 11.3. Деприкейтнуть doc_type
**Op:** `deprecate_doc_type` (WRITE, HMAC HARD)
**Payload:**
```json
{
"op": "deprecate_doc_type",
"env": "prod",
"name": "Реестр Изменений"
}
```
**Ошибка:** `E_DOC_TYPE_IN_USE, data.in_use_count=N` — есть недеприкейтнутые документы. Перед деприкейтом надо `bulk_deprecate_documents` их.
### 11.4. Использование в register_document
После регистрации нового doc_type — его сразу можно указать в `register_document`:
```json
{
"op": "register_document",
"env": "prod",
"product": "my_product",
"doc_type": "Реестр Изменений",
"version": "v1.0",
"owui_file_id": "...",
"sha256": "...",
"size": 12345,
"description": "Первый changelog my_product v1.0"
}
```
## §12-NEW. Описание документа (поле description)
`description` — опциональная аннотация конкретной версии документа (для чего нужен, что внутри). Длина ≤512 символов.
### 12.1. Задать при регистрации
Опциональное поле в `register_document` (см. §11.4). Валидация:
- `E_DESCRIPTION_TOO_LONG` — > 512 символов.
- `E_DESCRIPTION_BLANK` — только пробелы (пустая строка — ок, будет NULL).
### 12.2. Обновить у существующего документа
**Op:** `update_document_description` (WRITE, HMAC HARD)
**Payload:**
```json
{
"op": "update_document_description",
"env": "prod",
"doc_id": 480,
"description": "Новое описание"
}
```
**Гейт:** `actor.principal == documents.uploaded_by` OR `actor.principal ∈ arch_actors`. Иначе — `E_FORBIDDEN`.
### 12.3. Чтение
Все read-op возвращают `description` в объекте документа: `get_document`, `list_documents`, `full_state_report.documents[*]`, `onboard.docs[*]`.
### 12.4. Промоут между env
`promote_document` копирует `description` из исходной записи. Опциональный `override_description?` — заменить при промоуте.
## §13. Совместимость (напоминание)
Old-клиенты (broker < 0.9.0a8) не видят полей `description` и не могут звать новые op — получают `E_UNKNOWN_OP`. При апдейте клиента до 0.9.0a8 старые документы имеют `description=NULL` (миграция 032 не заполняет back-fill).
### Исходная версия v0.28 (doc_id=519)
# ADB Гайд Пользователя v0.28
Delta vs v0.27. Остальное — без изменений.
## §H-REMOVED. HMAC полностью удалён (0.9.0a9)
Начиная с broker **0.9.0a9** (миграция `033_hmac_removed`) вся HMAC-подпись клиентских WRITE-запросов **удалена**. Пользователь больше:
- не заводит `hmac_secret` / `key_id` при регистрации узла;
- не хранит `[credential]` в `actor.toml` (секция игнорируется, клиент выдаёт warning `hmac_removed`);
- не подписывает запросы заголовком `X-ADB-HMAC-*`;
- не может звать `rotate_node_credential` — op удалена (см. §H-REMOVED.2).
**Что осталось единственным механизмом авторизации:**
- Полный `actor{product,node,product_version,session_type,session_id,request_id,emitted_at,source_url,principal}` в payload каждой WRITE-op. Все поля обязательны; отсутствие любого → `E_INVALID_ACTOR` (`class=input`).
- Для op с ограниченными правами — гейт `actor.principal ∈ arch_actors` (см. §34 Гайда Архитектора).
### §H-REMOVED.1. Что делать с существующей `actor.toml`
- Секцию `[credential]` можно **не удалять** — клиент 0.2.0+ её игнорирует.
- Env-переменные `ADB_KEK`, `ADB_BOOTSTRAP_SECRET`, `ADB_HMAC_REQUIRE_SECRETS` больше не нужны и не читаются. Можно снять из юнитов/окружения.
- Keyring-запись `ai_docs_broker/<node>` можно оставить или удалить — клиент к ней не обращается.
### §H-REMOVED.2. rotate_node_credential → E_OP_REMOVED
**Op:** `rotate_node_credential` (WRITE) — **REMOVED в 0.9.0a9**.
**Ответ:**
```json
{
"status": "error",
"error_code": "E_OP_REMOVED",
"errors": [{"code":"E_OP_REMOVED","message":"operation 'rotate_node_credential' was removed in 0.9.0a9","class":"contract"}]
}
```
Op будет полностью снят с whitelist в 0.9.0b1. До этого — заглушка, возвращающая `E_OP_REMOVED` на любой payload.
### §H-REMOVED.3. Изменения в `register_node`
Op `register_node` **больше не выдаёт** `hmac_secret`/`key_id`. Поля `bootstrap_secret` / `rotate_of` в payload — deprecated no-op (сервер игнорирует, но не отклоняет для обратной совместимости).
**Успех (0.9.0a9):**
```json
{"status":"ok","data":{"node":"heavy02","env":"prod","created":true}}
```
Полей `hmac_secret`, `key_id`, `expires_at` в ответе больше нет.
## §11-UPDATED. Управление типами документов (без HMAC)
Все правила §11 v0.27 сохраняются, кроме маркировок:
| Op | Было в v0.27 | Стало в v0.28 |
|---|---|---|
| `register_doc_type` | WRITE, HMAC HARD | WRITE, actor обязателен |
| `deprecate_doc_type` | WRITE, HMAC HARD | WRITE, actor обязателен |
| `list_doc_types` | READ | READ (без изменений) |
Из перечня ошибок **удалено**: `E_HMAC_REQUIRED`, `E_HMAC_INVALID`, `E_HMAC_MISSING`, `E_HMAC_REPLAY`, `E_NODE_REVOKED`, `E_INSECURE_BOOTSTRAP`, `E_CURRENT_KEY_MISMATCH`. Эти коды не возникают ни при каких условиях в 0.9.0a9+.
**Пример `register_doc_type` payload (v0.28):**
```json
{
"op": "register_doc_type",
"env": "prod",
"name": "Реестр Изменений",
"description": "Список изменений между версиями продукта",
"actor": {
"product": "perplexity-arch",
"node": "heavy02",
"product_version": "0.9.0a9",
"session_type": "perplexity",
"session_id": "…",
"request_id": "…",
"emitted_at": "…",
"source_url": "…",
"principal": "andy.krivenko@gmail.com"
}
}
```
Заголовки `X-ADB-HMAC-*` больше не требуются и игнорируются, если переданы.
## §12-UPDATED. Описание документа (без HMAC)
Единственное изменение — маркировка `update_document_description`:
| Op | Было в v0.27 | Стало в v0.28 |
|---|---|---|
| `update_document_description` | WRITE, HMAC HARD | WRITE, actor обязателен + гейт principal |
Гейт остаётся: `actor.principal == documents.uploaded_by` OR `actor.principal ∈ arch_actors`. Отказ — `E_FORBIDDEN`. Все остальные правила §12 v0.27 в силе.
## §13-UPDATED. Совместимость
- Клиент `ai_docs_broker_client < 0.2.0` (со старой HMAC-подписью): сервер **игнорирует** заголовки, обрабатывает по actor'у. Клиент продолжает работать без правок.
- Клиент `ai_docs_broker_client >= 0.2.0`: HMAC-подпись физически удалена, `hmac_sign.py` — no-op shim, зависимость `keyring` убрана.
- Old-клиенты broker < 0.9.0a8 (без description и новых op) — правила совместимости из v0.27 в силе.
## §H-REMOVED.4. Что делать при 401 / E_HMAC_* на wheel < 0.9.0a9
Если получаете `E_HMAC_REQUIRED` или `E_HMAC_INVALID` — узел работает на **старом wheel**. Проверьте `health.version` — должен быть ≥ `0.9.0a9`. Если ниже — договоритесь с ИИ-Архитектором о плановом обновлении. Обходить HMAC на старом wheel запрещено.
## §H-REMOVED.5. Таблица node_credentials
Таблица `node_credentials` переименована в `_deprecated_node_credentials_2026_09_15` (миграция 033). Данные сохраняются 30+ дней для аварийного отката, после чего удаляются миграцией 034 (не раньше 2026-10-15). Никакие op к этой таблице больше не обращаются.
### Исходная версия v0.29 (doc_id=558)
# ADB Гайд Пользователя v0.29
Delta vs v0.28. Всё из v0.28 остаётся в силе. Здесь — новый обязательный стандарт запуска сервисов ADB (wheel/venv/log).
## §R-RUNTIME. Стандарт запуска сервисов ADB на узле (heavy02 и далее)
Начиная с broker **0.9.0a13** сервис `ai_docs_broker` (и любой другой сервис-продукт ADB) **обязан** запускаться по трём слотам: `wheel` → `venv` → `log`. Это минимальный воспроизводимый контур; без него UEPR получает `verdict: RED`.
Правило действует для всех environments (prod/dev), для всех node, для всех сервис-продуктов ADB. Инструменты (`test_guide`, `ai_h2_shared_validation`) — вне scope §R-RUNTIME, для них см. §R-TOOLS (будущий раздел).
### §R-RUNTIME.1. Слот WHEEL (собранный пакет)
Сервис читает Python-код **только из установленного `.whl`-пакета**, лежащего в `<venv>\Lib\site-packages\<package>\`.
**Обязательно:**
- В `<product_root>\dist\<package>-<version>-py3-none-any.whl` лежит собранный wheel текущей версии.
- Wheel зарегистрирован в ADB (`register_wheel`) с sha256, совпадающим с sha256 файла на диске.
- Wheel развёрнут через `register_deploy` (`status=active`) на этом узле.
- Wheel **установлен в venv** через `pip install --force-reinstall <path\to\wheel>` (не `pip install -e .` и не через `PYTHONPATH`).
- `pip show <package>` в venv возвращает `Location: <product_root>\.venv\Lib\site-packages` (ровно тот путь; если `Location` указывает в `src\` — deploy сломан).
**Запрещено:**
- Запуск сервиса, читающего код из `src\`, `bin\`, `source\src\` или иной папки исходников на этом узле в prod-контуре.
- Модификация файлов в установленном `site-packages\<package>\` вручную (bit-for-bit неизменяемо между deploy).
- `pip install -e .` в prod-venv (editable-install запрещён; для dev-контура — только с явным тех-долгом и сроком).
**Как проверить:**
```powershell
& "C:\H2\<product>\.venv\Scripts\pip.exe" show <package>
# Location должен указывать в C:\H2\<product>\.venv\Lib\site-packages
& "C:\H2\<product>\.venv\Scripts\python.exe" -c "import <package>; print(<package>.__file__)"
# __file__ тоже указывает в site-packages, не в src
```
UEPR-поле `execution_endpoint.paths.installed_package` **обязано** заканчиваться на `\.venv\Lib\site-packages\<package>` (или Linux-эквивалент). Иначе `verdict: RED`, тех-долг `T-RUNTIME-WHEEL-BYPASS`.
### §R-RUNTIME.2. Слот VENV (окружение запуска)
Один продукт — один venv — одна папка.
**Обязательно:**
- venv лежит в `<product_root>\.venv\` (Windows) или `<product_root>/.venv/` (Linux). Никаких `bootstrap_venv\`, `.venv_dev\`, `venv_r4\` в prod.
- Python-интерпретатор — стандартной версии платформы (текущий стандарт: **Python 3.14.3**; отклонение — только через `Стандарт → Python Version Deviation`).
- В venv установлены: (а) сам пакет продукта из `.whl`, (б) `h2_shared` актуальной версии из `.whl`, (в) все runtime-зависимости — все из `.whl`.
- venv **пересоздаётся с нуля** при каждом deploy: `python -m venv .venv && .venv\Scripts\pip install <wheel>`.
- `pip list --format=json` в venv соответствует полю `dependencies` в UEPR (расхождение = баг deploy).
**Запрещено:**
- Шеринг venv между продуктами (например, `owui_perl_bridge_health_monitor` использует venv от `owui_perl_bridge` — anti-pattern).
- Ручной `pip install <pkg>` в prod-venv после deploy без соответствующего `register_wheel` в ADB.
- Смешение src-install и wheel-install в одном venv.
**Как проверить:**
```powershell
& "C:\H2\<product>\.venv\Scripts\python.exe" --version # → Python 3.14.3
& "C:\H2\<product>\.venv\Scripts\pip.exe" list --format=json > venv_actual.json
# Diff venv_actual.json vs UEPR.dependencies → пусто
```
UEPR-поле `runtime.interpreter_version` фиксирует фактическую версию Python. Отклонение от стандарта платформы без явного тех-долга → `verdict: RED`.
### §R-RUNTIME.3. Слот LOG (файлы логов)
Каждый сервис пишет структурированный лог в стандартное место с ротацией.
**Обязательно:**
- Два файла: `<product_root>\logs\svc_stdout.log` и `<product_root>\logs\svc_stderr.log`.
- **Ротация:** по размеру — **50 MB × 10 файлов** (стандарт NSSM: `AppRotateFiles=1`, `AppRotateBytes=52428800`, `AppRotateSeconds=0`). Alternative: суточная с хранением 14 дней.
- **Формат строки:** одна строка = одна запись. Начинается с ISO-времени UTC, далее уровень, логгер, сообщение.
```
2026-09-16T14:33:12.845Z INFO ai_docs_broker.ops.documents register_document product=ai_docs_broker doc_id=549 ok request_id=e944...
```
Обязательные поля в строке WRITE-op: `request_id`, `actor.principal`, `op`, статус (ok/error), при ошибке — `error_code`.
- **Уровень:** INFO по умолчанию для всех WRITE-op и всех переходов состояния; WARNING/ERROR — обязательно (с полным traceback для ERROR); DEBUG — только под флагом env-переменной.
- **Audit-строка каждой WRITE-op** попадает в `svc_stdout.log` (или отдельный `audit.log` — на выбор реализации, но с той же ротацией).
**Запрещено:**
- Логи без ротации (растут неограниченно → диск переполнится → сервис упадёт).
- Логи в нестандартном месте (`C:\temp\`, `%APPDATA%\`, каталоге пользователя).
- Логи без ISO-времени (нельзя корректно сортировать / джойнить с другими сервисами).
- Логирование секретов, HMAC-токенов (упразднён, §H-REMOVED, но правило остаётся), содержимого документов целиком (только sha256 + размер).
**Как проверить:**
```powershell
Get-ChildItem C:\H2\<product>\logs\svc_stdout.log | Format-List Length, LastWriteTime
# Свежая запись за последние минуты (сервис живой)
Get-Content C:\H2\<product>\logs\svc_stdout.log -Tail 5
# Строки начинаются с ISO-времени, содержат уровень и логгер
```
UEPR-поле `logs.rotation` **обязано** содержать конкретное правило (например, `"50MB x10"` или `"daily x14"`); `null` в prod → `verdict: RED`.
### §R-RUNTIME.4. UEPR verdict-гейт
При регистрации UEPR (`doc_type="UEPR"`) для сервис-продукта ADB верификатор проверяет три условия:
| Слот | Проверка | При нарушении |
|---|---|---|
| WHEEL | `paths.installed_package` заканчивается на `\.venv\Lib\site-packages\<package>` **и** `attest_checks.files_sha256.wheel == wheels.sha256(active deploy)` | `verdict: RED`, `T-RUNTIME-WHEEL-BYPASS` в `tech_debts_open` |
| VENV | `runtime.interpreter` начинается с `<product_root>\.venv\Scripts\python.exe` **и** `runtime.interpreter_version == <platform_python_standard>` | `verdict: RED`, `T-RUNTIME-VENV-NONSTANDARD` |
| LOG | `logs.stdout` не `null`, `logs.rotation` — строка вида `<size|daily> x <count>` (не `null`) | `verdict: RED`, `T-RUNTIME-LOG-NOROTATE` |
Все три `GREEN` → UEPR `verdict: GREEN`. Любое `RED` → UEPR регистрируется (evidence-first), но `attest_state: needs_fix` и попадает в отчёт валидации следующей итерации.
### §R-RUNTIME.5. Порядок действий при deploy сервис-продукта ADB
Единый обязательный порядок (реализация — в deploy-скрипте, ручные шаги запрещены):
1. Собрать wheel: `python -m build --wheel` → `dist\<package>-<version>-py3-none-any.whl`.
2. `register_wheel(env, product, product_version, sha256, filename)` в ADB.
3. Остановить сервис: `nssm stop <service>`.
4. Пересоздать venv: `rm -rf .venv && python -m venv .venv`.
5. Установить пакет: `.venv\Scripts\pip install --force-reinstall dist\<wheel>`.
6. Проверить `pip show <package>` → `Location` в `site-packages`.
7. Настроить/подтвердить NSSM-ротацию (`AppRotateFiles=1`, `AppRotateBytes=52428800`).
8. Запустить сервис: `nssm start <service>`. Убедиться `nssm status → SERVICE_RUNNING`.
9. `register_deploy(env, product, node, product_version, wheel_id)` в ADB.
10. Собрать UEPR по Гайду UEPR v0.2, `register_document(doc_type="UEPR", ...)`. Ожидаемый `verdict: GREEN`.
Пропуск любого шага фиксируется тех-долгом в tech-debt-log с классом `T-RUNTIME-DEPLOY-SKIP-<N>`.
### §R-RUNTIME.6. Тех-долги, вводимые §R-RUNTIME (для tech-debt-log v40)
Введение §R-RUNTIME открывает следующие тех-долги (по текущему состоянию heavy02, §7 Отчёта ADB-108):
- **T-RUNTIME-WHEEL-BYPASS-ADB** — `ai_docs_broker` читает из `src\` вместо `site-packages\` (UEPR 551).
- **T-RUNTIME-LOG-NOROTATE-ADB** — `ai_docs_broker` `logs.rotation: null` (UEPR 551).
- **T-RUNTIME-VENV-SHARED-HM** — `owui_perl_bridge_health_monitor` использует `.venv` от `owui_perl_bridge` (UEPR 556).
- **T-RUNTIME-WHEEL-BYPASS-OB** — `h2_openbrowser` читает из `bin\` (UEPR 557).
- **T-RUNTIME-WHEEL-MISSING-ORCH** — `ai_connect_orchestrator` не собирает wheel (UEPR 555).
- **T-RUNTIME-DEPLOY-DRIFT-ROO** — `owui_roo_bridge` работает 0.5.8 через `bridge_work\...20260831...\venv_r4\` вместо 0.7.17 в стандартном месте (UEPR 540).
Первым по §R-RUNTIME приводится в порядок `ai_docs_broker` (задача ADB-109), затем — остальные сервисы отдельными задачами.
### §R-RUNTIME.7. Область действия
- **Применимо:** все сервис-продукты ADB на любом узле H2, prod-контур.
- **Не применимо:** инструменты (`test_guide`, `ai_h2_shared_validation`), библиотеки (`h2_shared`), временные пробы (`brief099_probe_*`).
- **Отсрочка dev-контур:** dev-узлы имеют льготный период 14 дней с даты регистрации v0.29 (до **2026-09-30**); после — правило действует и в dev.
## §CHANGELOG v0.30-consolidated
- Создана полная кумулятивная редакция для TD-2026-09-16-07 (T-DOCS-DELTA-BAN).
---
## §CHANGELOG v0.31 vs v0.30
Правка по фактам сессии 2026-09-17 (Арх #6 ошибочно вывел «WRITE через фасад невозможен», основываясь на нечёткой формулировке §5.1):
- **§5.1** переписан однозначно: если клиент передал actor в теле — используется actor клиента; автоподстановка фасада работает только когда actor отсутствует и не проходит валидацию WRITE.
- Список обязательных полей actor приведён в соответствие с фактическим `broker_hints.required_fields` брокера 0.9.0a14 (7 полей). `hmac_phase` и `caller_kind` помечены как устаревшие.
- Задокументирован tech-debt TD-2026-09-17-07: `actor_source_url` не пишется в audit-таблицу.
## §CHANGELOG v0.31-r1 vs v0.31-consolidated
- **§5.5** убраны упоминания ложно-срабатывающих правил `line_count >= 0.9 * prev` и `first_500_lines_overlap >= 50%`. Оставлен только запрет «Delta vs vN» / «Остальное — без изменений».
- Добавлена ссылка на TD-2026-09-17-08 (замена на §CHANGELOG-валидатор в 0.9.0a15).
- Сами правила в брокере пока ещё работают — будут убраны в 0.9.0a15.