docs(platform): align connector, EDP, and deploy canon

This commit is contained in:
Codex
2026-07-17 18:09:55 +03:00
parent 2dd6e33a54
commit 31e078d6e5
8 changed files with 831 additions and 414 deletions
+184 -220
View File
@@ -1,274 +1,238 @@
# ADR: L2-owned external connectors and provider-neutral Data Plane
# ADR: внешние коннекторы принадлежат NDC L2 workflow
Статус: **accepted**.
Дата: 2026-07-14.
Дата: 2026-07-16.
Владелец решения: NODE.DC Platform.
## Контекст
NODE.DC — платформа разработки. Подключение внешнего API не должно создавать
ещё один provider-specific сервис, в котором навсегда зашиты логика клиента,
нормализация и правила отображения. Иначе каждый новый account или новый тип
объекта превращается в изменение Platform runtime.
NODE.DC состоит из двух разных слоёв:
Нужна одна повторяемая форма: Platform даёт безопасные границы, контракт
хранения и выдачи данных; изолированный workflow NDC Agent L2 является
адаптером конкретного API и остаётся редактируемым через предоставленный
Codex/Engine MCP.
- платформенный слой даёт NDC L1, NDC L2, Ontology, credentials, Data Products
и Foundry-boundaries;
- пользовательские автоматизации собирают из этих возможностей конкретную
бизнес-логику.
Это решение заменяет provider-adapter часть
`ADR_EXTERNAL_PROVIDER_DATA_PLANE.md` и все provider-specific runtime
предписания `ADR_GELIOS_DATA_PLANE.md`. Они сохраняются как исторические
черновики, но не являются каноном для новой реализации.
Новый account, provider credential, tenant, расписание или интерфейс не должны создавать
новый platform service и не должны требовать изменения NODE.DC source. Команда
NODE.DC подключается только для нового поставщика либо для расширения
подтверждённых capabilities и ontology уже поддержанного поставщика.
Gelios — первый живой источник и acceptance-кейс этого канона, а не отдельная
архитектурная ветка. Документ заменяет provider-runtime решения из
`ADR_EXTERNAL_PROVIDER_DATA_PLANE.md` и `ADR_GELIOS_DATA_PLANE.md`; те
документы остаются только историей решения.
## Решение
### 1. Адаптер внешнего API принадлежит L2
### 1. Пакет поставщика создаётся один раз
Один изолированный L2 workflow представляет одно connection instance и
является единственным местом для:
Каждый поддержанный поставщик получает один версионируемый **provider package**.
Он является знанием платформы о внешнем API и содержит:
- обращения к API поставщика через ссылку на credential из Engine;
- выбора read-capability, cursor/pagination, rate limit, retry и расписания;
- получения raw envelope, разбиения большого ответа на native batch-операции;
- семантического mapping к версии ontology и формирования canonical facts;
- idempotency key, watermark и lifecycle источника;
- deploy/run/execution/trace через Engine MCP.
- стабильный `providerId` и версии подтверждённого API;
- credential contract без значения секрета;
- каталог safe-read capabilities, pagination/rate-limit metadata и response
shapes;
- mappings из provider fields в версии Ontology;
- совместимые Data Products и scrubbed contract fixtures;
- явно отделённый каталог команд без активного command transport.
L2 не хранит значение provider secret или writer token: он использует только
Engine-bound credential references. Plaintext writer token выдаётся trusted
provisioner ровно один раз при create/rotate binding и затем хранится только в
Engine credential store, привязанном к этому L2; External Data Plane хранит
лишь его hash. Provisioner читает отдельный runner-owned secret file, который
read-only монтируется только в EDP и позднее в dedicated Engine provisioner,
работающий под выделенным UID/GID `11006`; это не shared `.env`, не
`NODEDC_INTERNAL_ACCESS_TOKEN` и не provider credential. До deployment этого
provisioner `EXTERNAL_DATA_PLANE_PROVISIONING_ENABLED=false`, поэтому issuance
routes fail closed. Token не попадает в L2 graph/profile, contract artifact,
execution log/trace, raw envelope, Foundry или UI. Command/write-capabilities
не получают transport route в read workflow.
Пакет не является runtime service, scheduler, базой данных или customer
configuration. Он расширяется только когда фактически подтверждён новый API,
новый тип данных или новая ontology revision.
Для новой учётной записи создаётся новый instance/profile этого workflow с
другой credential reference и connection configuration. Это не требует
изменения Platform source. Если поставщик раскрывает новый объект или поле,
сначала расширяется ontology/capability contract, затем изменяется именно
соответствующий L2 workflow.
Одна учётная запись поставщика задаётся данными, а не кодом:
### 2. Platform Data Plane нейтрален к provider и домену
`provider package + credential reference + connection profile + NDC L2 workflow instance`
Platform предоставляет один versioned **External Data Plane**. Он принимает
batch по внутреннему аутентифицированному контракту, хранит raw envelope с
retention/provenance, canonical facts, current/history projections и отдаёт
scoped data products/realtime updates. В нём запрещены:
Поэтому второй account или другая provider credential pair создаёт ещё один credential/profile и
workflow instance. Платформенный source, Data Plane и Foundry при этом не
меняются.
- ветвления по названию provider, customer, account, vehicle или renderer;
- provider field mapping, unit allowlist, business filtering и visual rules;
- provider token, прямой browser-to-provider доступ и command transport.
### 2. NDC L1 проектирует, NDC L2 workflow исполняет
Его canonical write-форма, которую Data Plane валидирует и сохраняет после
авторизации, содержит только нейтральные элементы:
NDC L1 получает пользовательское намерение, проверяет доступные capabilities и
Ontology, проектирует или изменяет разрешённый NDC L2 workflow через NDC MCP и
анализирует execution evidence.
```text
source: providerId + tenantId + connectionId
contract: contractVersion + ontologyRevision + dataProductId
batch: runId + sequence + idempotencyKey + receivedAt
raw: optional restricted ref + contentType + hash + retention policy
facts: stable sourceId + semanticType + observedAt + attributes + geometry?
```
Один изолированный NDC L2 workflow представляет один connection instance и
владеет исполняемой механикой:
Для нового L2 writer-а это не wire-форма. Он вызывает
`POST /internal/data-plane/v1/data-products/:dataProductId/publish` с bearer
writer token и формой `nodedc.data-product.publish/v1`, в которой вообще нет
`source`, contract metadata, transport или persistence policy. Любой caller
scope и scope headers запрещены.
- safe-read вызовами provider API через credential reference;
- pagination, cursor, retry, rate limit, batch size и collection cadence;
- проверкой response shape и разбиением ответа на items;
- mapping к точной ontology revision;
- idempotency, watermark и публикацией canonical facts;
- private workflow state, когда он действительно нужен.
External Data Plane разрешает token в собственный immutable writer binding
`(tenantId, connectionId, providerId, allowedDataProductIds, expiresAt)`,
проверяет active/non-expired binding, совпадение `providerId` и разрешение
`dataProductId`, затем сам materializes canonical `source` с tenant/connection
и только после этого валидирует и сохраняет batch. Присланный caller scope
отклоняется, а не merge/override-ится. Изменение tenant, connection, provider,
allowed data products или срока требует нового binding; для существующего
binding допустимы только token rotation и revoke.
Provider-specific mapping сначала реализуется штатными workflow nodes и малым
Code-преобразователем. Это позволяет проверить реальный API без преждевременного
создания custom nodes. В custom NDC nodes переносится только повторившаяся и
доказанная **платформенная boundary-механика**, а не уникальная логика
поставщика.
Выпуск, rotation и revoke binding принимаются только от dedicated provisioning
principal с runner-owned secret file; он не монтируется в shared `.env` или L2.
Shared legacy bearer не может создавать writer capability.
### 3. Credentials являются данными connection instance
Идентификатор источника стабилен в пределах `(providerId, connectionId,
sourceId)`. Отсутствие объекта в очередном ответе помечается lifecycle-state
или временем последнего наблюдения; запись и её история не удаляются.
Gelios выдаёт ровно два provider secrets: access token и refresh token. Текущий
HTTP request binding `httpBearerAuth` использует access token. Автоматический
refresh в принятом runtime не доказан, поэтому provider package фиксирует его
как `operator_managed`; ни один из token values не попадает в graph, package,
Ontology, Data Plane, Foundry, execution logs, MCP или Ops. Новый account или
provider-issued token pair означает новые native credential records и
connection instance, но не новую Platform-сущность.
### 3. Граница данных и интерфейса
Локальное имя credential (например, с суффиксом `read access`) не является
provider scope. В target-контракте Read-классификацию задаёт allowlisted
method/endpoint в capability catalog и Engine workflow policy; тот же access
token нельзя называть отдельным «read token» или «write token» только из-за
label. Сейчас deployed Engine safe-ref policy ограничивает generic HTTP
credential только по host, но ещё не связывает его с package/version и exact
method/path. Поэтому Gelios `GET /api/v1/units` пока является декларативной
capability, а не завершённой runtime-security гарантией; canonical acceptance
требует capability-bound Engine policy и её MCP proof.
```text
Provider API (safe read)
-> Engine provider-credential reference
-> L2 connector instance (adapter + mapping + batches)
-> Engine writer-credential reference
-> External Data Plane Data Product publish (scope materialized server-side)
-> External Data Plane (generic persistence + projections)
-> scoped data product / realtime stream
-> Foundry binding / user interface
```
Writer capability для публикации Data Product — отдельный внутренний native NDC
L2 credential, не третий Gelios token. Generic Engine/Platform control plane
генерирует capability внутри native credential boundary, сохраняет её там же и
передаёт EDP только SHA-256 digest вместе с точным provider, connection и
набором Data Products. Пользователь и MCP получают только opaque
reference/status. Capability не записывается в graph, provider package, env,
file, Ops или trace и не копируется через пользовательский UI.
Ontology Core описывает semantic types, связи, capability catalog и mapping
versions, но не хранит runtime payloads или секреты. Foundry получает только
approved data product и решает presentation: pins, visibility, layers and
filters. Оно не получает provider endpoint или credential.
Широкий credential sink, resolver/daemon с произвольной записью secret и любой
provider-specific credential service запрещены. Нужна одна узкая операция
`ensure data-product publish grant`: scope выводится из granted L1→L2 target,
зарегистрированного connection profile и разрешённого Data Product; issuance,
rotation и native binding должны быть idempotent, CAS/crash-safe и auditable.
Engine генерирует capability внутри credential boundary и передаёт EDP только
SHA-256 digest через idempotent binding key + generation; EDP не возвращает
plaintext. Новая generation создаётся до переключения node reference, а старая
отзывается только после успешного bind/acceptance.
Старые ручные EDP `POST/rotate` endpoints, которые возвращают capability один
раз, включаются отдельным legacy-флагом и не входят в canonical acceptance.
Digest-only managed endpoint имеет независимый флаг и принимает только
Ed25519-signed Engine service requests: exact audience/method/request target/raw
body hash входят в подпись, timestamp ограничен по skew, nonce защищён bounded
fail-closed replay cache. Legacy provisioner bearer на managed routes не
действует. EDP получает только deployment public key; matching private key
остаётся только внутри Engine server boundary. Endpoint остаётся выключенным,
пока key provisioning, Engine signer и exact native credential binding policy
не пройдут runtime acceptance.
В deployed Engine MCP этой операции пока нет — это текущий platform gap перед
canonical publish proof, а не действие пользователя. Это решение не заявляет
автоматический refresh Gelios: до отдельного runtime proof он остаётся
`operator_managed`.
### 4. Полнота без entity allowlist
### 4. External Data Plane нейтрален к поставщику
Collection profile выбирает разрешённые **read-capabilities**, а не список
конкретных объектов. Если выбранный read endpoint возвращает все доступные
источнику сущности, L2 передаёт все валидные элементы. Новые сущности
добавляются автоматически; скрытие/отображение — задача data product/UI, а не
сбора. Технические лимиты существуют только как размер batch, backpressure,
quota и защита от повреждённого ответа, но не как бизнес-фильтр по ID.
Platform предоставляет один versioned External Data Plane. Он принимает
canonical facts через scoped writer binding, хранит current/history
projections и публикует snapshot/patch contracts. В нём запрещены:
### 5. Масштабирование и native NDC Agent nodes
- ветвления по provider, customer, account, entity или renderer;
- provider field mapping и бизнес-фильтрация;
- provider credential, endpoint, schedule или command transport;
- caller-supplied tenant/connection scope.
L2 не запускает отдельный execution на каждую сущность. Он использует native
nodes NDC Agent: HTTP Request, Split Out, Split In Batches/Loop Over Items,
Aggregate, Postgres (когда нужен private workflow state), Set/If/Merge,
Schedule Trigger and Respond to Webhook. Code node допустим только как малый
преобразователь boundary-shape, когда эквивалентной native node нет; он не
становится скрытым сервисом или provider database.
`NDC Data Product Publish` отправляет только
`nodedc.data-product.publish/v1`. External Data Plane materializes immutable
scope из writer binding, проверяет разрешённый Data Product и его ontology
revision, затем сохраняет batch.
Shared telemetry/history не записывается L2 напрямую в физические таблицы
Platform Postgres: это создало бы coupling к schema. Direct Postgres допустим
для private state конкретного workflow или отдельной project-owned базы.
Общий контур использует только External Data Plane contract и bulk batches.
EDP runtime импортирует только package subpath
`@nodedc/external-provider-contract/data-plane`. Его deploy artifact и image
содержат только provider-neutral wire validators; `providers/gelios`, mappings,
fixtures и tests туда не входят. Изменение или добавление provider package не
пересобирает и не перезапускает EDP: каталог поставщиков разворачивается через
Engine/Ontology/control-plane путь отдельно.
### 5.1. Каталог custom nodes NODE.DC
Collection cadence, history cadence и presentation cadence независимы:
Встроенные узлы runtime сохраняют свои штатные названия (`HTTP Request`,
`Schedule Trigger`, `Loop Over Items` и т. п.). Любой узел, код которого
принадлежит NODE.DC, обязан одновременно выполнять три условия:
- NDC L2 забирает источник с частотой, нужной бизнес-задаче;
- current projection принимает каждое валидное изменение;
- declarative history policy может хранить все точки или sampling;
- Foundry читает snapshot+patch и отдельно ограничивает частоту render.
- видимое имя начинается с `NDC `;
- runtime type принадлежит package namespace `n8n-nodes-ndc.*`;
- package-level test отклоняет публикацию узла без этого префикса и namespace.
Для разной частоты БД и интерфейса не создаются второй provider sink, отдельный
gateway или параллельный прямой push в renderer.
Первый канонический набор состоит из:
### 5. Полнота означает все сущности разрешённой capability
- `NDC Data Product Publish` — runtime write boundary L2 → Data Plane;
- `NDC Data Product Read` — scoped current snapshot read по reader grant;
- `NDC Foundry Binding` — deploy/control-plane связь Data Product с
`Application → Page → typed slot`, но не транспорт каждого realtime tick.
Connection profile выбирает safe-read capabilities, а не зашитый в Platform
список entity IDs. Если разрешённый endpoint возвращает все доступные credential
сущности, NDC L2 обрабатывает каждый валидный item. Новый объект появляется
автоматически.
`NDC Foundry Output` не используется как техническое имя: оно ошибочно
подразумевает прямой transport L2 → renderer. Provider-specific adapter,
mapping и collection profile остаются логикой конкретного L2 workflow на
штатных nodes; они не оформляются как custom NODE.DC nodes и не добавляют
provider branch в Data Plane или Foundry.
Пользовательская фильтрация, слои и видимость находятся после сбора — в
automation/Data Product/Foundry. Технические ограничения допустимы только как
pagination, quota, batch size, backpressure и защита от повреждённого ответа.
`NDC Foundry Binding` отправляет только
`nodedc.foundry.binding-upsert/v1`. Её постоянный L2 credential — отдельный
revocable `ndc_fndbg_*` workload grant с allowlist точных
`Application → Page → Binding → Slot → Data Product` targets. Короткоживущая
`fnd1.*` capability интерактивного Foundry MCP, browser session, EDP
writer/reader grant и `NODEDC_INTERNAL_ACCESS_TOKEN` для этой ноды запрещены.
### 6. Custom NDC nodes ограничены платформенными границами
Runtime node не содержит URL, endpoint, provider ID, tenant ID, connection ID,
token, contract version или history cadence. Узел выбирает только разрешённый
Data Product; всё остальное materializes из opaque writer/reader binding и
immutable Data Product definition.
Первый канонический набор:
Package `n8n-nodes-ndc` устанавливается как штатный private community package в
`/home/node/.n8n/nodes/node_modules`, чтобы n8n `PackageDirectoryLoader`
сохранил namespace `n8n-nodes-ndc.*`. `~/.n8n/custom` и
`N8N_CUSTOM_EXTENSIONS` запрещены для этого пакета: они создают namespace
`CUSTOM.*`. Ручное копирование или `npm install` в живом container, patch
Engine core и подмена built-in node запрещены. Production использует
проверенный offline tarball, immutable release, atomic current/previous switch,
read-only mount и restart всех n8n execution processes; acceptance завершается
только когда Engine schema и MCP catalog возвращают точные package-qualified
types.
- `NDC Data Product Publish` — NDC L2 → External Data Plane;
- `NDC Data Product Read` — scoped snapshot/patch read;
- `NDC Foundry Binding` — control-plane связь Data Product с
`Application → Page → typed slot`.
### 5.2. Realtime delivery contract
Эти nodes не содержат provider ID, tenant ID, connection ID, endpoint, token,
mapping или cadence. Runtime package сохраняет технический namespace
`n8n-nodes-ndc.*`, но пользовательские документы и интерфейсы используют
только терминологию NDC.
Новый writer использует:
`NDC Foundry Binding` не транспортирует каждый realtime tick. Он создаёт
постоянную связь интерфейса с Data Product; Foundry затем читает его
snapshot+patch contract.
```text
POST /internal/data-plane/v1/data-products/:dataProductId/publish
Authorization: Bearer <opaque writer binding>
```
### 7. Реальный Gelios acceptance-кейс
Body имеет schema `nodedc.data-product.publish/v1` и содержит только batch
identity и canonical facts. Data Plane одной транзакцией:
Первая версия provider package должна доказать путь:
1. проверяет idempotency;
2. обновляет current projection только более новым или изменившимся фактом;
3. применяет declarative history policy (`none`, `all`, `sampled`);
4. добавляет changed facts в durable patch outbox;
5. фиксирует монотонный cursor.
`Gelios safe read → все доступные units → map.moving_object facts →
fleet.positions.current.v1 → Foundry map`
Reader grant получает snapshot `nodedc.data-product.snapshot/v1`, затем
подключается к SSE stream с `after=<snapshot.cursor>` или `Last-Event-ID`.
Каждый outbox event имеет schema `nodedc.data-product.patch/v1`. Если cursor
уже удалён retention policy, stream отвечает `409 resync_required`, и consumer
повторяет snapshot. Browser не получает Data Plane token или scope: Foundry BFF
разрешает persisted binding и читает server-only reader grant.
Canonical product использует ontology revision
`ontology.map.moving_object.v1` и только объявленные snake_case поля. NDC L2
не передаёт caller scope и не собирает собственный batch envelope вокруг
`NDC Data Product Publish`.
`snapshot+patch` в v1 является **bounded product contract**. Current projection
одного scoped Data Product не может содержать больше 5000 entity keys
`(sourceId, semanticType)`. Snapshot возвращает целую согласованную projection
и один barrier cursor из одной `REPEATABLE READ` transaction. Query-параметр
`limit` — только защитный потолок, а не размер страницы: если полная projection
не помещается, Data Plane отвечает `413 data_product_snapshot_limit_exceeded`
и consumer не начинает patch stream с неполной базой.
Acceptance выполняется по порядку:
Наивная pagination current snapshot по `sourceId`, offset или независимо
полученным page cursors запрещена: изменения между страницами могут быть
пропущены или продублированы относительно patch cursor. Product с ожидаемой
cardinality выше 5000 обязан **до включения realtime** выбрать один из двух
отдельно версионируемых контрактов:
1. Platform выполняет generic `ensure data-product publish grant`, выпускает
scoped EDP binding и атомарно сохраняет capability в native NDC L2
Credentials;
2. NDC MCP видит только совместимый opaque writer credential reference/status;
3. применить подтверждённый graph patch без legacy intake;
4. validate/preflight;
5. один успешный manual run и проверка execution/trace/Data Product;
6. только затем отдельным изменением добавить Schedule Trigger;
7. после доказанного snapshot+patch подключить Foundry binding.
- stable partitioning в несколько Data Products, где partition key является
частью definition, а каждый partition имеет собственный полный snapshot и
независимый patch cursor;
- новый query delivery contract с явно определёнными snapshot barrier,
continuation cursor, query scope и правилами перехода к patch stream.
### 8. Capacity и topology
Такой query contract не входит в `nodedc.data-product.snapshot/v1` и не может
быть имитирован полем `nextPageCursor`. До его отдельного утверждения runtime и
`NDC Data Product Read` работают только с bounded products до 5000 сущностей.
### 6. Порядок первой реализации
1. Версионировать нейтральный intake/read contract и поднять External Data
Plane без provider-specific logic.
2. Пересобрать существующий L2 proof в native-node pipeline: safe read →
split/batch → semantic mapping → generic append → safe summary. Никаких
provider ID filters и provider gateway endpoint.
3. Выполнить manual run, проверить execution/trace, idempotency and current
projection; только затем включить Schedule Trigger.
4. Provision immutable writer binding, one-time place its token into an opaque
Engine credential, then switch the L2 to
`/data-products/:dataProductId/publish` and remove caller scope/headers and
the shared legacy credential.
5. Подключить Foundry к data product current positions. История, геозоны и
новые сущности добавляются отдельными L2 collection profiles and ontology
revisions.
Количество одновременно активных NDC L2 проектов ограничивается фактическими
ресурсами железа и профилем нагрузки. Пока capacity проверяется оператором и не
автоматизируется. Канон не объявляет отдельные worker/webhook generations или
high-load topology, которых ещё нет в принятом runtime.
## Последствия
- `services/<provider>-gateway` не является шаблоном для новых интеграций.
Существующий experimental code не расширяется и не деплоится как часть этого
решения.
- Data Plane может иметь собственную БД/Timescale/PostGIS implementation, но
физическая схема остаётся внутренней деталью neutral service, а не API для
L2 или Foundry.
- Inline raw запрещён в L2 → Data Plane v1: до отдельного raw-vault допускается
только restricted ref/hash либо отсутствие raw envelope. Retention reference
вычисляется по серверному acceptance time, а не по timestamp из batch; Data
Plane выполняет bounded retention sweeps после готовности сервиса и по таймеру.
- Обычный Codex Desktop получает ровно те L2 grants, которые выданы владельцем
connection/workflow, и может безопасно развивать adapter только в этой
границе.
- `POST /internal/data-plane/v1/intake` остаётся временным migration-only route:
он выключен по умолчанию (`EXTERNAL_DATA_PLANE_LEGACY_INTAKE_ENABLED=false`),
требует `NODEDC_INTERNAL_ACCESS_TOKEN`, canonical scoped batch и совпадающие
scope headers. Новый или migrated L2 не получает этот shared token и не
использует fallback в legacy route. После миграции всех writers он удаляется.
- `services/<provider>-gateway` не является частью канона и не создаётся для
новых provider integrations. Существующий self-hosted Gelios Gateway и его
Timescale volume остаются frozen compatibility contour, воспроизводятся из
source/deploy и не изменяются новым L2 pilot без отдельного решения.
- Новый account или provider-issued access/refresh pair — configuration change,
а не platform release.
- Новый provider или неподдержанная capability — versioned provider/Ontology
change с contract tests.
- Существующий legacy L1/SDK workflow является frozen compatibility boundary:
новый L2 pilot его не редактирует, не отзывает его credential и не ставит его
вывод условием acceptance.
- Legacy `/internal/data-plane/v1/intake` остаётся выключенным migration-only
route и не используется новыми NDC L2 workflows.
- Команды устройствам остаются отдельным red-domain контуром с явным
подтверждением, scope, idempotency и аудитом.
- Foundry развивается после доказанного Data Product path; provider API и
credentials в Foundry не попадают.
+11 -5
View File
@@ -28,7 +28,7 @@ The worker receives only a pairing-bound Hub URL. The Hub verifies that the pair
It intentionally does not expose filesystem paths, evidence ledgers, credentials, raw payloads, live telemetry, databases, command dispatch, workflow mutation or Studio controls.
## Boundary for Gelios and future data services
## Boundary for external providers and runtime data
Ontology Core describes the canonical meanings and constraints:
@@ -36,15 +36,21 @@ Ontology Core describes the canonical meanings and constraints:
gelios.unit -> gelios.telemetry_snapshot -> gelios.position_fix -> map.moving_object
```
It does **not** serve the Gelios database or provider API. The future Gelios Gateway/Data API is a distinct capability with its own scope checks, data contract and transport. That capability may later be supplied to an AI Workspace run as another dynamic MCP server. Ontology then gives the assistant the names, relations, guardrails and allowed data-contract route; the data capability enforces access and returns live data.
It does **not** serve provider runtime data or call a provider API. Provider
access and mapping belong to the granted NDC L2 workflow; shared current and
history products belong to the provider-neutral External Data Plane. A scoped
Data Product read capability may later be supplied to an AI Workspace run as a
separate dynamic MCP server. Ontology supplies meanings, relations, guardrails
and the allowed contract route; the data capability enforces access and returns
live data.
This preserves one-way responsibility:
- Ontology Core: semantics, contracts, aliases, guardrails and context advice.
- Gelios Gateway/Data API: access-scoped telemetry and history reads.
- External Data Plane: access-scoped Data Product snapshots and updates.
- Command Gateway: separate red-domain command route, explicit confirmation and audit.
- Engine L2: workflow orchestration using granted capabilities.
- Studio: later presentation consumer, outside this implementation.
- NDC L2 workflow: provider access, collection and mapping using granted capabilities.
- Foundry: presentation consumer, outside this implementation.
## Live catalog updates without AI Workspace rule redeploy