NODEDC_PLATFORM/docs/ADR_L2_OWNED_EXTERNAL_CONNE...

16 KiB
Raw Permalink Blame History

ADR: внешние коннекторы принадлежат NDC L2 workflow

Статус: accepted. Дата: 2026-07-16. Владелец решения: NODE.DC Platform.

Контекст

NODE.DC состоит из двух разных слоёв:

  • платформенный слой даёт NDC L1, NDC L2, Ontology, credentials, Data Products и Foundry-boundaries;
  • пользовательские автоматизации собирают из этих возможностей конкретную бизнес-логику.

Новый 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. Пакет поставщика создаётся один раз

Каждый поддержанный поставщик получает один версионируемый provider package. Он является знанием платформы о внешнем API и содержит:

  • стабильный providerId и версии подтверждённого API;
  • credential contract без значения секрета;
  • каталог safe-read capabilities, pagination/rate-limit metadata и response shapes;
  • mappings из provider fields в версии Ontology;
  • совместимые Data Products и scrubbed contract fixtures;
  • явно отделённый каталог команд без активного command transport.

Пакет не является runtime service, scheduler, базой данных или customer configuration. Он расширяется только когда фактически подтверждён новый API, новый тип данных или новая ontology revision.

Одна учётная запись поставщика задаётся данными, а не кодом:

provider package + credential reference + connection profile + NDC L2 workflow instance

Поэтому второй account или другая provider credential pair создаёт ещё один credential/profile и workflow instance. Платформенный source, Data Plane и Foundry при этом не меняются.

2. NDC L1 проектирует, NDC L2 workflow исполняет

NDC L1 получает пользовательское намерение, проверяет доступные capabilities и Ontology, проектирует или изменяет разрешённый NDC L2 workflow через NDC MCP и анализирует execution evidence.

Один изолированный NDC L2 workflow представляет один connection instance и владеет исполняемой механикой:

  • 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, когда он действительно нужен.

Provider-specific mapping сначала реализуется штатными workflow nodes и малым Code-преобразователем. Это позволяет проверить реальный API без преждевременного создания custom nodes. В custom NDC nodes переносится только повторившаяся и доказанная платформенная boundary-механика, а не уникальная логика поставщика.

3. Credentials являются данными connection instance

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-сущность.

Локальное имя 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.

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.

Широкий 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. External Data Plane нейтрален к поставщику

Platform предоставляет один versioned External Data Plane. Он принимает canonical facts через scoped writer binding, хранит current/history projections и публикует snapshot/patch contracts. В нём запрещены:

  • ветвления по provider, customer, account, entity или renderer;
  • provider field mapping и бизнес-фильтрация;
  • provider credential, endpoint, schedule или command transport;
  • caller-supplied tenant/connection scope.

NDC Data Product Publish отправляет только nodedc.data-product.publish/v1. External Data Plane materializes immutable scope из writer binding, проверяет разрешённый Data Product и его ontology revision, затем сохраняет batch.

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 путь отдельно.

Collection cadence, history cadence и presentation cadence независимы:

  • NDC L2 забирает источник с частотой, нужной бизнес-задаче;
  • current projection принимает каждое валидное изменение;
  • declarative history policy может хранить все точки или sampling;
  • Foundry читает snapshot+patch и отдельно ограничивает частоту render.

Для разной частоты БД и интерфейса не создаются второй provider sink, отдельный gateway или параллельный прямой push в renderer.

5. Полнота означает все сущности разрешённой capability

Connection profile выбирает safe-read capabilities, а не зашитый в Platform список entity IDs. Если разрешённый endpoint возвращает все доступные credential сущности, NDC L2 обрабатывает каждый валидный item. Новый объект появляется автоматически.

Пользовательская фильтрация, слои и видимость находятся после сбора — в automation/Data Product/Foundry. Технические ограничения допустимы только как pagination, quota, batch size, backpressure и защита от повреждённого ответа.

6. Custom NDC nodes ограничены платформенными границами

Первый канонический набор:

  • 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.

Эти nodes не содержат provider ID, tenant ID, connection ID, endpoint, token, mapping или cadence. Runtime package сохраняет технический namespace n8n-nodes-ndc.*, но пользовательские документы и интерфейсы используют только терминологию NDC.

NDC Foundry Binding не транспортирует каждый realtime tick. Он создаёт постоянную связь интерфейса с Data Product; Foundry затем читает его snapshot+patch contract.

7. Реальный Gelios acceptance-кейс

Первая версия provider package должна доказать путь:

Gelios safe read → все доступные units → map.moving_object facts → fleet.positions.current.v1 → Foundry map

Canonical product использует ontology revision ontology.map.moving_object.v1 и только объявленные snake_case поля. NDC L2 не передаёт caller scope и не собирает собственный batch envelope вокруг NDC Data Product Publish.

Acceptance выполняется по порядку:

  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.

8. Capacity и topology

Количество одновременно активных NDC L2 проектов ограничивается фактическими ресурсами железа и профилем нагрузки. Пока capacity проверяется оператором и не автоматизируется. Канон не объявляет отдельные worker/webhook generations или high-load topology, которых ещё нет в принятом runtime.

Последствия

  • 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 не попадают.