---
title: "OCETS Plant Registry Specification"
version: "1.1"
status: "Architecture Review Candidate"
release: "July 2026"
identifier: "OCETS-REGISTRY-1.1"
---

# OCETS Plant Registry Specification

**Document:** 4 of 5  
**Type:** Normative Registry Specification  
**Version:** 1.1  
**Status:** Architecture Review Candidate  
**Compatibility:** OCETS 1.1

## 1. Purpose

The Plant Registry is the authoritative, schema-enforced source of truth for OCETS platform objects, ownership, topology, capabilities, and controlled metadata. It supports validation, configuration generation, discovery, authorization scope, documentation, and historical interpretation.

## 2. Registry Principles

- Every logical object has exactly one authoritative definition and stable ID.
- Plant and Organization IDs are globally unique; other IDs are unique within their documented scope.
- Transport addresses, hostnames, protocol fields, and replaceable hardware identifiers are not semantic identity.
- Released Registry revisions are immutable, traceable, and available to interpret retained data.
- Generated configuration derives from Registry data and does not become another source of truth.
- Credentials, private keys, tokens, and other secrets SHALL NOT be stored in the Registry.

## 3. Object Model

```text
Organization
  -> Portfolio
      -> Plant
          -> Asset
              -> Device
                  -> Measurement Point
                      -> Capability

Plant -> Topology -> Relationship -> typed registered endpoints
```

A Plant belongs to exactly one Organization and MAY belong to multiple Portfolios of that Organization. Relationships do not replace the required ownership references in the hierarchy.

## 4. Controlled Vocabularies

| Vocabulary | Allowed values |
|---|---|
| lifecycle `status` | `planned`, `active`, `maintenance`, `disabled`, `retired` |
| `role` | `grid`, `load`, `pv`, `battery`, `inverter`, `meter`, `transformer`, `busbar`, `collector`, `environment` |
| `energy_form` | `electricity_ac`, `electricity_dc`, `thermal`, `environmental`, `operational` |
| `phase` | `l1`, `l2`, `l3`, `n`, `total` |
| `direction` | `import`, `export`, `charge`, `discharge`, `generation`, `consumption`, `bidirectional` |
| topology `kind` | `electrical`, `physical`, `telemetry` |
| relationship `type` | `contains`, `feeds`, `connected_to`, `measures`, `controls`, `powered_by` |
| endpoint `kind` | `plant`, `asset`, `device`, `measurement_point` |

## 5. Organization and Portfolio

An Organization requires `id`, `name`, and `status`; it MAY declare `data_residency_region` and tags. Its ID is globally unique and establishes the tenant, governance, and authorization boundary.

A Portfolio requires `id`, `organization_id`, `name`, and `status`. Portfolio IDs are unique within one Organization. Portfolios group Plants and do not change Plant identity or ownership.

## 6. Plant

A Plant requires `id`, `organization_id`, `name`, `timezone`, and `status`. It MAY declare `portfolio_ids`, `country`, `operator`, `commissioned_at`, `data_residency_region`, and tags.

Every `portfolio_id` SHALL resolve to a Portfolio in the same Organization. Plant IDs are globally unique. Country values SHOULD use ISO 3166-1 alpha-2 and timezone values SHOULD use IANA timezone identifiers.

## 7. Asset and Device

An Asset requires `id`, `plant_id`, `type`, `name`, and `status`. It MAY declare vendor, model, serial number, location, and commissioning time. Asset IDs are unique within a Plant.

A Device requires `id`, `plant_id`, `asset_id`, `role`, `energy_form`, and `status`. It MAY declare vendor, model, protocols, implementation-specific communication data, profiles, and capabilities. Device IDs are unique within a Plant.

A Device claiming `edge_collector_observability` SHALL use `role=collector`, `energy_form=operational`, and list every required profile Metric. Its ID SHALL NOT derive solely from hostname, IP address, or replaceable serial number.

## 8. Measurement Point and Capability

A Measurement Point requires `id`, `plant_id`, `device_id`, `type`, and `name`. It MAY declare role, energy form, phase, string, MPPT, direction, nominal voltage, or parent Measurement Point. IDs are unique within a Plant.

A Capability references a canonical Metric name from the versioned Canonical Metric Catalogue. Local capabilities SHALL use an `x-<organization>-` namespace. Capabilities do not imply that current data is healthy or available.

## 9. Topology

A Topology requires `id`, `plant_id`, `kind`, immutable positive integer `version`, `name`, `status`, and `valid_from`; it MAY declare `valid_to`. Topology IDs are unique within a Plant, while `(plant_id, id, version)` identifies a specific graph version.

Versions of the same active Topology SHALL have non-overlapping validity intervals. `valid_to` SHALL be later than `valid_from`. Grid connections, transformers, busbars, inverters, batteries, loads, collectors, and their semantic points SHALL be registered as Assets, Devices, or Measurement Points rather than embedded anonymous nodes.

## 10. Relationship

A Relationship requires `id`, `plant_id`, `topology_id`, `topology_version`, `type`, `from`, `to`, `status`, and `valid_from`; it MAY declare `valid_to`. Endpoints are objects with `kind` and `id`.

All endpoints SHALL exist in the Relationship Plant. `contains` SHALL be acyclic. `connected_to` is symmetric and SHALL occur only once for an unordered endpoint pair. Other relationship types are directed. Electrical `feeds` and `connected_to` graphs MAY contain cycles.

Recommended endpoint constraints are:

| Type | From | To |
|---|---|---|
| `contains` | Plant, Asset, or Device | Asset, Device, or Measurement Point |
| `feeds` | Asset or Measurement Point | Asset or Measurement Point |
| `connected_to` | Asset or Measurement Point | Asset or Measurement Point |
| `measures` | Device or Measurement Point | Asset or Measurement Point |
| `controls` | Device | Asset or Device |
| `powered_by` | Asset or Device | Asset or Measurement Point |

`controls` records a semantic relationship only; command authorization and behavior remain outside OCETS v1.1.

## 11. Registry Example

```yaml
version: "1.1"
registry_id: "example-registry"
revision: "2026-07-13T10:00:00Z"
organizations:
  - id: "example-energy"
    name: "Example Energy"
    status: "active"
portfolios:
  - id: "germany"
    organization_id: "example-energy"
    name: "German Plants"
    status: "active"
plants:
  - id: "plant-example"
    organization_id: "example-energy"
    portfolio_ids: ["germany"]
    name: "Example Plant"
    timezone: "Europe/Berlin"
    country: "DE"
    status: "active"
assets:
  - id: "transformer-01"
    plant_id: "plant-example"
    type: "transformer"
    name: "Transformer 01"
    status: "active"
  - id: "busbar-01"
    plant_id: "plant-example"
    type: "busbar"
    name: "Main Busbar"
    status: "active"
devices:
  - id: "meter-01"
    plant_id: "plant-example"
    asset_id: "transformer-01"
    role: "meter"
    energy_form: "electricity_ac"
    status: "active"
    capabilities: ["active_power", "voltage", "current"]
measurement_points:
  - id: "mp-transformer-secondary"
    plant_id: "plant-example"
    device_id: "meter-01"
    type: "transformer_secondary"
    name: "Transformer Secondary"
    role: "transformer"
    energy_form: "electricity_ac"
topologies:
  - id: "primary-electrical"
    plant_id: "plant-example"
    kind: "electrical"
    version: 1
    name: "Primary Electrical Topology"
    status: "active"
    valid_from: "2026-07-01T00:00:00Z"
relationships:
  - id: "rel-transformer-busbar"
    plant_id: "plant-example"
    topology_id: "primary-electrical"
    topology_version: 1
    type: "feeds"
    from: {kind: "asset", id: "transformer-01"}
    to: {kind: "asset", id: "busbar-01"}
    status: "active"
    valid_from: "2026-07-01T00:00:00Z"
```

## 12. Normative JSON Schema

Registry implementations SHALL validate against JSON Schema Draft 2020-12 or an equivalent enforceable contract. The complete normative schema is maintained as `implementation/registry/schema/plant-registry-v1.1.schema.json`; its `$id`, version constant, definitions, and controlled vocabularies are part of OCETS-REGISTRY-1.1.

Implementations MAY add stricter local validation but SHALL NOT accept data forbidden by the normative schema. Cross-reference, tenant-boundary, graph, interval, catalogue, and profile rules from Section 13 remain mandatory even where JSON Schema cannot express them.

## 13. Validation Rules

Validation SHALL ensure:

- all required IDs are unique in their documented scopes;
- ownership and endpoint references exist and remain within one Organization and Plant;
- Portfolio membership never crosses an Organization;
- Topology and Relationship validity intervals are ordered and active versions do not overlap;
- `contains` graphs are acyclic and symmetric Relationships are not duplicated;
- capabilities reference known versioned Metrics or valid local extensions;
- claimed conformance profiles are complete;
- implementation addresses and secrets do not replace or enter semantic identity.

## 14. Registry API Profile

The base path is `/api/ocets/registry/v1`. `GET /` returns service metadata and the current immutable Registry revision. Collections and `/{id}` resources SHALL exist for `organizations`, `portfolios`, `plants`, `assets`, `devices`, `measurement-points`, `relationships`, `topologies`, `metric-definitions`, and `event-types`.

`GET /snapshot` returns one revision-consistent bulk representation. `GET /changes?since=<revision>` returns retained changes after a known revision. Collections use opaque `cursor`, bounded `limit`, and optional `organization_id`, `plant_id`, `status`, and `updated_since` filters where applicable.

Every success response identifies `registry_revision` and emits an `ETag`. `If-None-Match` SHALL be supported. Cursors SHALL remain bound to the revision that created them. Errors contain `code`, `message`, and `request_id`. Authentication and tenant authorization are mandatory; an implementation SHALL avoid revealing whether an unauthorized cross-tenant resource exists.

The profile is read-only. Registry mutation, approval, deployment, and rollback APIs are implementation-specific.

## 15. Generated Outputs

The Registry MAY generate collector configuration, transport mappings, storage labels, dashboards, alerts, API caches, documentation, and topology diagrams. Outputs SHALL identify their source Registry revision and SHALL NOT become independent sources of truth.

## 16. Change Governance

Registry changes SHALL be reviewed, attributable, and associated with an immutable revision. Breaking identity changes require a migration plan. Deprecated and retired objects remain resolvable for historical interpretation. Security-sensitive changes and manual corrections require an audit record.
