Conventions
The rules every ODS schema, module and vocabulary follows: kinds, names, descriptions and structure.
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 noIdsuffix. A list of ids has a plural name:features. - A point in time ends in
Atand holds an RFC 3339 date-time:createdAt,generatedAt. The bounds of an Interval are itsstartandend. A length of time is aduration(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. typesays 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
$refcan 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
typearrays (useanyOf), so that strict validators such as Ajv compile every file. An object withpropertiesstates"type": "object". - Entities extend the base:
"$ref": "Entity.json","type": "object", their ownproperties, 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 (
$refandx-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,deprecatedorunreleased.x-ods-changes: one note for each release that changed the schema.