docs(platform): align connector, EDP, and deploy canon
This commit is contained in:
@@ -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 не попадают.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user