Conventions

The rules every ODS schema, module and vocabulary follows: kinds, names, descriptions and structure.

Draft

The rules can still change before the first release.

The rules that every ODS schema, module and vocabulary follows. The schema tests (@opencycle/ods-schema) check each rule that a program can check; review checks the others. A new schema, field or code follows these rules from its first version.

1. Kinds

Each schema has one kind, in x-ods-kind.

Kind What it is Id
document The root of an ODS document. Required
pillar One of the four groups in a document: risk, context, environment, methodology. None
entity A record that other records point at. It extends Entity. Required
part A record that its parent owns and embeds. Optional
datatype Data with no identity, such as a Value or a Location. None
base Fields that entities share. A base is never used on its own. Required

One home. A record lives in the one pillar that answers its question (see the glossary, "Pillars"). Other records point at it by id. A parent embeds the parts that it owns. A field that points at a record owned elsewhere holds that record's id, and names the record's schema with x-ods-ref. A field that can point at a record of any schema, such as an Evidence's subject, has x-ods-ref: "*".

2. Names

One word means one concept. The glossary defines each word. A schema, field or description uses a glossary word only with its glossary meaning. A change that adds a word adds its glossary entry.

Schemas. A singular noun in PascalCase that names the thing, not its role: Criterion, Emission, OperatingState.

Fields.

  • camelCase: receptorClass.
  • A list has a plural name: sources, windows.
  • A field that holds another record's id is named after that record (flow, instrument) or after the part it plays (issuer, holder), with no Id suffix. A list of ids has a plural name: features.
  • A point in time ends in At and holds an RFC 3339 date-time: createdAt, generatedAt. The bounds of an Interval are its start and end. A length of time is a duration (ISO 8601). One window of time is an Interval; a window that repeats, such as night-time, is a Period.
  • No units in a name. A quantity is a Value, and the Value names its unit: "height": { "amount": 4, "unit": "m" }, not "height_m": 4. A plain number is allowed only when its unit never changes, and its description names the unit, as a Location's heights in metres do.
  • No abbreviations, except one that a cited standard defines, such as crs (ISO 19111). A symbol that a cited standard defines can be a code in a vocabulary, with the standard named in its description.
  • type says what sort of thing a record is, from a list. "Kind" is used only for the kinds of schemas in section 1.

Codes. Each enum value and each vocabulary code is lower snake_case: ground_type, onsite_station. A code in a namespace has dots between its parts: ca.ab.aer_licence. A code from another standard keeps that standard's spelling: GeoJSON types (Point), unit symbols (dB, m/s), vertical datums (EGM2008), registry codes of coordinate reference systems (EPSG:3400).

3. Descriptions

Each schema and each field has a description. Write it in plain English: short full sentences, active voice, present tense.

  • A schema: the first sentence says what the record is: "A [glossary word] that …". The next sentences say what it holds and how it is used.
  • A field: a noun phrase or a short sentence: "The flow that ran." Say what a missing field means: "Leave it out when the amount has no unit." A field that is a $ref can use the description of its target.
  • Enum values: each has a title and a description in x-ods-options.
  • Standards: when a definition comes from a published standard, name the standard and its section: "As in ISO 14224:2016, levels 6 to 8."
  • Only the standard. No product names, no names of one producer's systems, and no internal decision numbers. A description holds what a reader of the standard needs, not how one producer makes or stores the data.

4. Structure

  • Closed objects. An object refuses keys that it does not declare, except keys that start with x-. An extension key names its owner: x-<organization>-<name>. A free-form object says so with "x-ods-open": true.
  • Lists hold their items directly, with no wrapper objects.
  • Portable. No union type arrays (use anyOf), so that strict validators such as Ajv compile every file. An object with properties states "type": "object".
  • Entities extend the base: "$ref": "Entity.json", "type": "object", their own properties, then "unevaluatedProperties": false.
  • Examples. Each schema has at least one example, and each example is valid. An entity has a minimal example (its required fields only) and a full one.

The running example. Examples tell one story where they can: Wellsite 04-12 in Alberta, with a gas compressor that runs loaded or idle, a dwelling 450 m to the north-east, the night-time limits of AER Directive 038, a weather station 8 km away and a survey with a sound level meter. The examples are one dataset: an id that an example points at is the id of a record that an example defines.

5. Core and modules

ODS Core holds what every domain needs: the document, the pillars, the entities and the generic carriers (Value, Axis, Statistic, Property, Path, Evidence, File, Trace, Finding, Comparison, Expression). A grid is a Value with spatial axes; a time series is a Value with a time axis. Places and shapes follow places and shapes. A module, such as ODS Acoustics, adds:

  • vocabularies: the codes for Core fields that name a vocabulary (x-ods-vocabulary), such as acoustic quantities and band sets;
  • module schemas: stricter forms of Core schemas, such as a sound emission that must be in decibels. A module schema refers to the Core schema it narrows ($ref and x-ods-narrows) and adds no fields.

Quantities. Each module lists what its amounts can describe in one quantities vocabulary, with the unit and the valid range of each term. A Property's type, an Axis's quantity, an Emission's type, an Evidence's observed and a Criterion's metric all take codes from these vocabularies (x-ods-vocabulary: "*/quantities"), so one code means one thing everywhere. A Value for a quantity uses the term's unit: a producer converts, so a reader never has to. A trace step's input or output names its quantity the same way. This keeps what a unit cannot say: a level's weighting is part of the quantity (a_weighted_sound_pressure_level), and its unit is dB.

A level at a distance. A level stated at a distance from its source, such as 60 dB at 50 m, is an Emission of that level with a distance Property. It is not a Path: a Path is a route between two places, and a distance with no direction names no second place.

A document that is valid against a module schema is also valid against Core, so a reader that knows only Core can read every document.

The two-domain rule. A need that two domains share becomes a Core generic. A need of one domain becomes a module vocabulary or a module schema.

6. Personal information

Each field has a class, in x-ods-personal:

Class Holds
public Data with no limit. A field without x-ods-personal is public.
confidential Commercial data, such as an engine's settings.
personal Data that identifies a person or a household, or can find one: names, contact details, a home's address or exact place, complaint text, and audio that may hold voices.

Some fields are personal only in context. These rules raise them:

Record When Fields that become personal
Stakeholder type is person name, description, identifiers, links
Feature receptorClass is dwelling or care_facility name, description, identifiers, location, geometry
Evidence its subject is a Feature that the rule above covers location
File its mediaType is audio/* or image/* the file
Trace step value its step is a question with answerType text value

A writer works out which classes a document holds from these annotations and rules, so a producer cannot leave one out. A redacted copy drops personal fields, moves a home's place to a coarser one, and replaces ids with hashes salted for each package.

7. Status and changes

  • x-ods-status: draft, released, deprecated or unreleased.
  • x-ods-changes: one note for each release that changed the schema.