Open Operational Telemetry
# OpenOT (OOT)
**Open Operational Telemetry**: a vendor-neutral specification for source-stamped event records emitted directly by industrial controllers.
> OTel is for IT. OpenOT is for OT.
## What it is
OOT defines how a PLC or PEA emits an audit-grade, sequence-numbered event log directly from the controller. Each record is generated at the source with its provenance attached, instead of being reconstructed downstream by SCADA tag polling.
The spec covers four artifacts:
| Layer | What it is | Document |
| --------------- | -------------------------------------------------- | ---------------------------------------------------- |
| Logical model | Event record fields and semantics | [`spec/core.md`](spec/core.md) |
| Wire format | Compact binary encoding for an in-PLC ring buffer | [`spec/wire-format.md`](spec/wire-format.md) |
| Doc format | JSON encoding for consumers (MES, historian, AI) | [`spec/doc-format.md`](spec/doc-format.md) |
| Definition file | Schema registry binding wire IDs to logical fields | [`spec/definition-file.md`](spec/definition-file.md) |
## Why it exists
Today's industrial event and audit records are reconstructed downstream by tag polling. Consequences:
* Anything not hand-mapped is lost.
* Provenance is reconstructed, not source-stamped, so the record is not self-verifying.
* Changing MES or historian re-touches validated controller code.
* GMP audit-trail completeness (21 CFR Part 11) is unprovable; gaps surface at validation, not at design.
* Data is unstructured for OEE, predictive analytics, and AI.
OOT fixes this by emitting events at the source, with sequence numbers and source-stamped provenance, so completeness is provable rather than assumed.
## Architecture
```
PLC Translator (IT app) Consumer
┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ LogEvent FC │── ring buf ─▶│ Reads ring buf │ │ MES / │
│ emits │ (binary, │ + Definition file│── OOT-Doc ─▶│ AI agent / │
│ ID-only │ OOT-Wire) │ joins IDs → │ (JSON) │ audit store │
│ records │ │ names/messages │ │ │
└─────────────┘ └──────────────────┘ └──────────────┘
│ │
└──── definition-hash ─────────┘
validation (drift detection)
```
The **PLC** emits a fixed-width, ID-only event record into a ring buffer. Cheap to emit, cheap to store. No strings.
The **Translator** joins each record against a Definition File and produces human and agent-readable JSON. The Definition File is the schema registry; its hash must match the hash exposed by the PLC, or the Translator refuses to resolve and emits placeholder records.
The **Consumer** (MES, historian, batch-record engine, AI agent) receives the resolved record. No tag polling, no string overhead on the controller.
Translator and Consumer implementations are out of scope for this spec. OOT defines only the wire, document, and definition-file contracts between them.
## Reading map
| Role | Read in this order |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Plant owner, decision maker | This README, then [`spec/core.md`](spec/core.md) |
| PLC engineer, codegen author | [`spec/core.md`](spec/core.md), [`spec/wire-format.md`](spec/wire-format.md), [`spec/definition-file.md`](spec/definition-file.md) |
| MES, historian, AI consumer | [`spec/core.md`](spec/core.md), [`spec/doc-format.md`](spec/doc-format.md) |
| Standards reviewer | All of [`spec/`](spec/), plus the Lineage section below |
## Lineage
OOT is a synthesis of existing standards, not an invention. Every design decision traces to a recognized source.
* **Record shape**: BatchML `SingleEventType` (ISA-88 Part 4). Multi-actor identification, named-value bag, before/after values, alarm subtyping, extensibility.
* **ID, timestamp, and ack semantics**: OPC UA Part 5 `BaseEventType` and Part 9 `AcknowledgeableConditionType`. Globally unique EventId, source/receive time pairs, two-stage Acknowledge + Confirm, BranchId for re-tripped conditions, RefreshStart/End for reader reconnect.
* **Separation of payload and schema**: Linux kernel ring buffer (`printk`, `dmesg`), Windows ETW, Confluent Schema Registry, Protobuf with `.proto`. Compact wire records bound to a versioned definition file.
* **Cloud-native parallel**: OpenTelemetry Logs Data Model and Kubernetes `audit.k8s.io/v1` Event API. OOT applies the same principles to the OT layer that OTel applies in IT.
## Non-goals
* **Not software.** OOT is a specification. Implementations (vendor PLC codegen, Translator apps, conformance harnesses) live in separate repos.
* **Not the transport above the buffer.** Use OPC UA Data Access, Sparkplug B, MQTT, REST, whichever fits the deployment.
* **Not the consumer.** MES, historian, batch-record engine, AI agent: OOT just hands them a typed record.
* **Not pharma-specific.** GMP pharma is the wedge, but the spec covers discrete (auto, semiconductor, packaging) and continuous (chemicals, water) just as cleanly.
* **Not vendor-specific.** Reference implementations for Rockwell L5X and Siemens SCL share the same wire format and FC contract.
## Status
`v0.0`: design exploration. Not yet ratified. Authored in the open. Governance model TBD.
## License
Apache License 2.0. See [`LICENSE`](LICENSE).