feat(ontology): add device asset infrastructure domains

This commit is contained in:
Codex
2026-08-22 14:15:57 +03:00
parent 209f4f439e
commit e2ea7e177d
46 changed files with 1324 additions and 14 deletions
@@ -0,0 +1,115 @@
# Device Domain Ontology v0.1
Date: 2026-08-22
Status: product-required / source-evidenced baseline for Device Core direct onboarding and Device Plane operation.
## Purpose
This package gives Device Core a provider-neutral semantic contract for registering, composing, connecting, configuring, observing and governing devices. It is derived from the existing Device Core schemas and Device Plane contracts, but it does not copy runtime tables into Ontology Core.
New B2 trackers are onboarded directly through Device Core. Gelios remains a parallel legacy/provider source for already connected units and is not a prerequisite for new devices.
## Runtime authority
Device Core owns:
- owner/project and collection scope;
- stable device identities;
- restricted identifiers and opaque credential references;
- adapter packages, immutable adapter versions and model profiles;
- discovery and enrollment lifecycle;
- time-qualified Asset bindings;
- Edge registrations, routes and sessions;
- desired configuration revisions and reconciled state;
- typed command intents/events and audit;
- device observations and their publication to Data Products.
Ontology Core owns only meanings, relation vocabulary, guardrails and evidence routing. Foundry consumes approved Data Products. Neither Ontology Core nor Foundry executes enrollment, device traffic or commands.
## Source evidence mapping
The first package is source-evidenced by the existing Device Core migrations:
- migration 001: profiles, contours, discoveries, device instances, bindings and audit;
- migration 002: owner scopes, projects, collections and grants;
- migration 004: adapter packages/versions, model profiles, Edge registrations, routes, sessions and enrollment intents;
- migration 006: direct lifecycle and ownership transitions;
- migration 008: restricted identifiers and credential bindings;
- migration 010: resource bindings, configuration revisions/state, commands and events;
- migration 013: Edge endpoint, server name, trust, certificate identity, generation and lifecycle;
- migration 015: integration device id retained as a restricted external reference.
Table names remain implementation details. Canonical entity ids remain stable even if runtime storage is refactored.
## Direct B2 onboarding
The accepted lifecycle is:
```text
candidate evidence
└─▶ device.discovery
└─▶ authorized device.enrollment_intent
├─▶ device.device / device.tracking_device
├─▶ device.model_profile ─▶ device.adapter_version
├─▶ device.restricted_identifier (IMEI/serial/provider id)
└─▶ device.asset_binding ─▶ asset.asset
accepted traffic
└─▶ device.edge_registration
└─▶ device.route
└─▶ device.session
└─▶ observation.source / observations
```
Discovery never claims ownership. Enrollment requires an authorized owner/project, reviewed model profile and exact identifier policy. The B2-to-trike binding is independent and temporal; a device may exist before attachment, and an Asset may exist without a current tracker.
## Adapter boundary
Vendor/protocol specifics live behind `device.adapter_package`, immutable `device.adapter_version` and `device.model_profile`. A future open-source tracking or traffic stack may implement adapters, storage or protocol processing behind this boundary. Its tables and vendor vocabulary do not become product ontology.
## Edge channel
The canonical Edge channel remains Core-initiated and pinned-mTLS:
- Core approves Edge registration identity, endpoint, server name and trust material;
- Edge is replaceable and untrusted for business authority;
- a concrete `infrastructure.service_instance` realizes the Edge registration on a host;
- routes terminate only at an approved Edge registration;
- sessions bind a stable device to one approved route;
- Edge never owns the central business database, secret authority or arbitrary command policy.
## Configuration
`device.configuration_revision` is immutable desired state. `device.configuration_state` reconciles a desired revision with observed evidence and time. A new revision never rewrites the old one. Secrets remain opaque references and are resolved only by the owning service.
## Commands
Commands are a red domain:
- target is a stable Device id;
- command type and payload schema are declared by the approved model/adapter contract;
- authorization, TTL and idempotency are explicit;
- request, acceptance, dispatch, acknowledgement, expiry and failure are separate events;
- arbitrary shell, raw provider text, firmware, reboot or memory wipe is not implied by the current safe `typed-service-ping-v1` contract;
- Device Control Core is authoritative for accepting ACK and final outcome.
## Gelios coexistence
Provider records map explicitly:
- `gelios.tracker_device``device.tracking_device` through a source binding;
- `gelios.unit``asset.asset` through a source binding;
- `gelios.position_fix``observation.position_observation` through a versioned mapping;
- legacy signal/movement values remain their existing closed Gelios value contracts.
Provider collection and direct Device traffic may coexist. They must retain source provenance and must not silently merge conflicting identities.
## Acceptance
- New B2 can be enrolled without a Gelios connection.
- Trike Asset and B2 Device receive different stable ids.
- IMEI remains restricted and can be rotated/reconciled without replacing Asset identity.
- Traffic is rejected before enrollment/profile/route/Edge checks.
- Config revisions and command lifecycle are immutable/auditable.
- Runtime records stay in Device Core, not Ontology Core or Foundry.
@@ -2,7 +2,20 @@
Package: `catalog/domain-packages/gelios`
Status: `v1.1.0`, source-evidenced and product-required.
Status: `v1.2.0`, source-evidenced and product-required.
## Provider-neutral Asset and Device bridge
As of 2026-08-22 Gelios remains a provider/legacy domain and no longer acts as the implicit product identity model for new devices:
- `gelios.unit` may map to `asset.asset` only through an explicit versioned source binding;
- `gelios.tracker_device` may map to `device.tracking_device` only through an explicit restricted-identifier/source binding;
- `gelios.position_fix` may map to `observation.position_observation` while retaining source and mapping provenance;
- existing provider Data Products may continue to use their current `map.moving_object` projection;
- new composed Data Products use the Asset as the stable map subject and the tracker as the observation source;
- direct B2 onboarding through Device Core does not require a Gelios connection.
Provider ids, IMEI values and renderer ids never replace NODE.DC Asset or Device identity. Direct and Gelios observations may coexist but must not silently overwrite one another.
## Purpose and boundary
@@ -0,0 +1,114 @@
# Infrastructure Domain Ontology v0.1
Date: 2026-08-22
Status: product-required / source-evidenced baseline for Device Core infrastructure inventory and Edge topology.
## Purpose
This package models VPS and other compute infrastructure as a provider-neutral graph. It prevents the current UI requirement from becoming a one-off VPS form or a false extension of `integration.connection`.
The canonical layers are:
```text
infrastructure.host
├─exposes──────────────▶ infrastructure.endpoint
├─target_of────────────▶ infrastructure.deployment
├─runs─────────────────▶ infrastructure.service_instance
└─target_of────────────▶ infrastructure.management_session
infrastructure.deployment
└─uses─────────────────▶ infrastructure.configuration_revision
infrastructure.service_instance
├─realizes─────────────▶ infrastructure.deployment
├─exposes──────────────▶ infrastructure.endpoint
└─realizes─────────────▶ device.edge_registration
```
These are peer graph subjects, not a deep type hierarchy. Each has independent identity and lifecycle.
## Authority boundary
Device Core may own the operational inventory required for Device Plane hosts, Edge services, monitoring and configuration. The canonical deploy runner remains authoritative for NODE.DC Synology release application and acceptance. A future provider adapter may own VPS account provisioning. Ontology Core owns none of those runtime mutations.
`integration.connection` represents a provider account/capability connection. It is never a Host. A cloud account may expose many Hosts; one Host may run many Service Instances; one Deployment may create or update one or more instances.
## Host registration
A host record requires at minimum:
- stable NODE.DC host id;
- host kind/capability profile;
- project/owner scope;
- provider-neutral display metadata;
- one or more namespaced external references where available;
- explicit endpoint records with protocol, visibility and trust policy;
- secret references only, never credential values;
- lifecycle state and audit evidence.
Registration alone does not prove reachability or health. Those are observations.
## Deployment and service instance
`infrastructure.deployment` records delivery intent and outcome for a versioned artifact/configuration against a target Host. `infrastructure.service_instance` is the concrete running service reconciled to that deployment.
For Device Plane:
- an Edge container/process is a Service Instance;
- its Core-approved application identity is `device.edge_registration`;
- the VPS is the Host;
- its mTLS/HTTP endpoint is an Endpoint;
- the release action and source version are Deployment evidence.
None of those identifiers are interchangeable.
## Monitoring
Host and service monitoring uses `observation.health_observation` with:
- stable target id;
- check/property id;
- observed and received time;
- source and mapping version;
- value and evidence summary;
- freshness policy selected by the consuming Data Product.
No observation means unavailable evidence. It is not automatically equivalent to unhealthy. Host health, service health, Edge registration state and device transport state remain separate facets.
## Management session and console
Browser console is possible only as an app-owned privileged management session, not as an iframe with an SSH key and not as a Device command.
Required contract:
- explicit authorized actor and project scope;
- exact target Host;
- reason/ticket or approved workflow context;
- short expiry and revocation;
- server-side credential resolution through an opaque reference;
- no secret returned to the browser;
- session start/end and executed-operation audit;
- policy-controlled copy/upload/download and network egress;
- separate break-glass permission from safe monitoring.
The first product slice may register and monitor Hosts without exposing console. That is a complete safe increment, not a placeholder for arbitrary shell.
## Foundry projection
Foundry receives provider-neutral Data Products and semantic bindings:
- inventory/table: Host, endpoints, deployments, service instances;
- topology/graph: Host ↔ Deployment ↔ Service Instance ↔ Edge ↔ routes/devices;
- Inspector: current observations, configuration revision and provenance;
- map: only subjects with actual spatial observation or declared fixed location.
A VPS with no real coordinates does not receive invented map coordinates.
## Acceptance
- Host, endpoint, deployment, service instance and Edge registration use separate ids.
- Credentials are opaque references and do not enter Ontology, Data Products or browser state.
- Monitoring values carry source/time/freshness and do not mutate Host identity.
- Console, if implemented, is privileged, short-lived and audited.
- VPS map presentation is evidence-driven, never hardcoded.
@@ -0,0 +1,116 @@
# Observation Domain Ontology v0.1
Date: 2026-08-22
Status: product-required / source-evidenced baseline for Device Core telemetry, health and spatial projection.
## Purpose
Observation is the provider-neutral bridge from runtime evidence to Data Products, Foundry state facets and monitoring. It separates the subject from a time-qualified statement about that subject.
The package covers:
- generic observations;
- declared observed-property value contracts;
- source/mapping provenance;
- consumer-owned freshness policy;
- health observations;
- position observations.
It is deliberately separate from lifecycle events, desired configuration and commands.
## Canonical observation envelope
An owning runtime service publishes at least:
```text
observation_id
subject_id
subject_entity_id
property_id
value + value_type + optional unit
observed_at
received_at
source_id + mapping_version
quality/evidence metadata
```
Freshness policy is referenced by the consuming Data Product and includes TTL, grace and missing-value behavior. It is not silently embedded in the source value.
`observed_at` is when the described state existed. `received_at` is when NODE.DC accepted the evidence. Both are required where a source can delay or replay data.
## Properties and values
`observation.observed_property` defines exact semantics and allowed values. Provider field names are mapping inputs, not canonical property ids. A Data Product may expose only mapped properties and exact values declared by its contract.
Examples:
- host reachability;
- service readiness;
- Edge channel connectivity;
- device transport session state;
- latitude/longitude position;
- speed or battery measurement;
- provider-specific Gelios `signal_state` and `movement_state` retained as their existing closed value contracts.
Foundry profiles may style declared state facets. They may not invent `unknown`, `stale`, `offline` or aggregate health values unless the bound property contract defines them.
## Missing and stale evidence
Missing evidence means no acceptable observation is available. Expired evidence means an observation failed the selected freshness policy. Neither automatically means unhealthy.
If a product wants `unknown`, `unavailable` or `unhealthy`, the owning property contract must define the value and derivation rule. Derived values must retain source observations and mapping version.
This rule prevents three common conflations:
- source value vs consumer freshness;
- missing observation vs negative observation;
- health of Host vs health of Service/Edge/Device.
## Health observations
`observation.health_observation` targets one stable layer at a time:
- `infrastructure.host` for host reachability/resources;
- `infrastructure.service_instance` for service process/readiness;
- `device.edge_registration` for Core↔Edge channel acceptance;
- `device.device` for device-specific transport or service checks.
An aggregate status may be published only by a versioned derived-property contract that identifies its inputs, precedence and missing-data rules.
## Position observations
`observation.position_observation` includes coordinate reference, coordinates, observed time, source and quality. For direct B2 traffic the provenance chain is:
```text
asset.asset
◀─ active device.asset_binding ─ device.tracking_device
◀─ position observation source ─ device.session / adapter mapping
─▶ map.moving_object Data Product projection
```
The map subject remains the Asset. The B2 remains the source Device. The observation remains evidence. None becomes the renderer entity identity.
Infrastructure may use the same position contract for a real fixed or mobile location. An address label or datacenter name without resolved spatial evidence is insufficient.
## Provider mappings
Existing Gelios mappings remain explicit:
- `gelios.position_fix` can map to a position observation;
- `gelios.telemetry_snapshot` can produce generic observations only through a versioned property mapping;
- raw provider payloads remain restricted;
- direct B2 and Gelios observations retain distinct sources and can be reconciled without silent overwrite.
## Storage and retention
Ontology Core stores no runtime observations. Device Core, an External Data Plane or another owning telemetry service owns current state, history, retention, cursoring and replay. Data Products expose approved projections; Foundry is not a telemetry database.
## Acceptance
- Every observation names stable subject, property, source, observed time and received time.
- Freshness is explicit and separate from the source value.
- Missing evidence is not silently converted to unhealthy.
- Health checks target one infrastructure/device layer at a time.
- Position projection retains Asset, Device and Observation as separate subjects.
- Provider values reach Foundry only through versioned mappings.
@@ -0,0 +1,99 @@
# Party and Asset Domain Ontology v0.1
Date: 2026-08-22
Status: product-required / source-evidenced baseline for Device Core and Foundry composition.
## Purpose
This domain defines stable business actors and assets independently from application accounts, trackers, providers and renderers. It is intentionally a shallow graph. A subject acquires meaning through explicit relations and time-qualified assignments rather than through a deep inheritance tree.
The first accepted product case is Robot2B:
- a trike is `asset.asset`;
- B2 is a separate `device.tracking_device`;
- the active attachment is `device.asset_binding` with `valid_from`, optional `valid_to`, lifecycle state and provenance;
- a driver is `party.person` participating through a time-qualified `party.driver_role` and `asset.assignment`;
- IMEI remains `device.restricted_identifier` on the tracker;
- map presentation is a projection of the Asset through `map.moving_object`, backed by `observation.position_observation`.
Changing the tracker, driver, provider or renderer must not replace the trike identity.
## Authority boundary
Ontology Core owns canonical meanings, relation names, aliases, blocked conflations and evidence routing. It stores no party rows, PII, asset rows, assignments, positions or access decisions.
Owning products remain authoritative for runtime state:
- HUB/NDCAuth own users, memberships, identities and authentication;
- Device Core owns asset/device composition used by Device operations;
- business applications own people, organizations and role assignments in their contour;
- Data Products expose approved projections;
- Foundry renders those projections and does not create domain identity.
## Canonical graph
```text
party.person ──is_party──────────────▶ party.party
party.organization ──is_party───────▶ party.party
party.account ──represents_party────▶ party.party
party.driver_role ──assigned_to─────▶ party.person
party.driver_role ──operates────────▶ asset.asset
asset.asset ──classified_by─────────▶ asset.asset_type
asset.asset ──has_assignment────────▶ asset.assignment
asset.asset ──has_external_ref──────▶ asset.external_reference
asset.asset ──has_lifecycle_event───▶ asset.lifecycle_event
asset.asset ──projected_as──────────▶ map.moving_object
```
The relation record or owning runtime binding carries provenance and validity. A UI may show the current effective relation, but history must remain queryable.
## Identity rules
`asset.asset` uses a stable NODE.DC-owned identifier. External references are namespaced and replaceable. The following values may be indexed for reconciliation but may not become the Asset identity:
- IMEI or hardware serial;
- current tracker id;
- Gelios unit id;
- renderer entity id;
- current driver or owner id;
- project or collection id;
- display name.
`party.person`, `hub.user`, `ndcauth.identity`, `party.account` and `agent.identity` are separate source records. Their composition requires explicit bindings with source authority; matching display name or email alone is insufficient.
## Temporal assignments
Assignments use half-open validity semantics: `valid_from <= t < valid_to`; `valid_to = null` means the relation remains current. The owning service must prevent overlapping active assignments where the product contract requires exclusivity. Closing an assignment appends or transitions evidence; it does not erase the old relation.
Examples include:
- driver operates trike;
- organization owns/manages asset;
- asset belongs to an operational project;
- tracker is attached to asset;
- contact point is valid for a party.
## Foundry projection
Foundry consumes stable Data Product keys and semantic bindings. It may combine identity, technical profile, contacts, current position and state facets by stable subject id. It must not infer Party or Asset identity from a provider-specific payload.
An Asset can be shown on a map only when a bound Data Product supplies a valid position observation. Without spatial evidence, the same Asset remains available in table, graph or Inspector views.
## Gelios coexistence
Existing Gelios records remain provider evidence:
- `gelios.unit` can map to an Asset only through an explicit source binding;
- `gelios.tracker_device` can map to a Tracking Device only through an explicit device binding;
- these mappings do not make provider ids canonical;
- new B2 onboarding does not require Gelios.
## Acceptance
- Trike and B2 resolve to separate canonical subjects.
- Replacing B2 closes one binding and opens another without changing the Asset id.
- IMEI is restricted and absent from public Foundry projections unless an explicit field policy grants it.
- Driver is a temporal role, not a Person subtype or free-text Asset field.
- Map identity is the Asset/Data Product key, not a provider or renderer key.
@@ -31,3 +31,12 @@ Current working evidence artifacts:
- `EVIDENCE_LEDGER_ENGINE_DIRTY_BOUNDARY_P1.md`
- `EVIDENCE_LEDGER_ENGINE_WORKFLOW_P1.md`
- `ONTOLOGY_SERVICE_PLACEMENT_AND_USE_CASES.md`
Accepted additive domain-package baselines from 2026-08-22:
- `../PARTY_ASSET_DOMAIN_ONTOLOGY.md`
- `../DEVICE_DOMAIN_ONTOLOGY.md`
- `../INFRASTRUCTURE_DOMAIN_ONTOLOGY.md`
- `../OBSERVATION_DOMAIN_ONTOLOGY.md`
These packages keep Party, Asset, Device, Observation and infrastructure subjects in a shallow explicit graph. Runtime rows, telemetry, credentials, assignments and commands remain owned by their application services and are not stored in Ontology Core.