Standard / BUS-1 v0.2 / Clause 17

17 The JSON binding§

AGREED

17.1 Status§

This clause defines the first normative binding. Additional bindings MAY be defined later; an RDF binding is anticipated. A conformance claim MUST name the binding it was tested against. Documents are JSON per [RFC8259], UTF-8, no byte order mark.

17.2 The document envelope§

{ "busVersion": "0.2",
  "documentType": "presentation",
  "packageId": "urn:uuid:...",
  "generatedAt": "2026-07-26T09:15:00-05:00[America/Chicago]",
  "namespaces": { "ex": "https://example.com/bus-ext/v1" },
  "entities": [ ... ] }

documentType MUST match the type declared for that path in the manifest. Entity order within the array is NOT significant and MUST NOT be relied upon.

17.3 Naming and encoding rules§

  • Property names are lowerCamelCase and case-sensitive.
  • Class names are UpperCamelCase and always prefixed. Predicates are lowerCamelCase and always prefixed.
  • Symbol roles are lowerCamelCase segments separated by dots.
  • A property whose value is unknown MUST be omitted. An explicit null asserts the value is known to be absent, which is a different statement and MUST NOT be used to mean unknown.
  • An empty array asserts the collection is known to be empty. Where that is not the intent, omit the property.

The distinction between omission and null is not pedantry. In a model read by people who cannot ask the author what they meant, the difference between "we did not record this" and "there is none" is frequently the whole content of the field.

17.4 Schema validation§

SchemaValidates
bus-core.schema.jsonDatatypes, the entity base, and every core class including the presentation model.
bus-document.schema.jsonThe document envelope and the classes permitted for each documentType.
bus-manifest.schema.jsonThe manifest, including completeness, actuation, and dictionary declarations.

NOTE Implementation experience: an importer whose internal model is a set of typed classes will silently drop fields those classes do not declare, which violates preservation over comprehension (2.4) in a way no schema check detects. The reference implementation holds entities verbatim and layers interpretation on top; an implementer who maps onto typed models must round-trip the unmapped remainder explicitly.

The schemas use [JSONSCHEMA] draft 2020-12 and resolve cross-references by $id; a validator MUST be configured with all three as a registry. Schema validation is necessary and not sufficient: it cannot detect a dangling reference, a mismatched digest, an undeclared namespace, an undefined property, an inaccurate actuation declaration, or a false completeness declaration. Annex A group PK exists for those.

17.5 Canonical form§

A model document in canonical form is its [RFC8785] canonicalization with two rules applied first:

  1. The entities array is sorted ascending by id, compared as UTF-8 code point sequences.
  2. Within each entity, externalIds is sorted by scheme then value, classifications by system then code, and properties by definition. All other arrays retain their order, which is significant — notably mapping.ranges and routing.

Semantic equivalence, as used in 2.4 and Annex A, is: after canonicalization and after applying the identity mapping of test RT-1, the two documents are equal except where a difference is explicitly permitted by the applicable test.

Two envelope fields are permitted differences under every round-trip test: generatedAt and packageId. They identify the act of serialization, not the model, and requiring them to survive a round trip would make honest re-export impossible. Everything else in the envelope, including namespaces, is compared.

NOTE Digests in the manifest are computed over stored bytes, not canonical form, because a receiver must verify integrity before parsing.

17.6 JSON-LD compatibility§

The binding is designed to be interpretable as JSON-LD without modification. This version does not define a normative context document and an implementation MUST NOT depend on one. The intent is that an RDF binding can be added later without changing the JSON on the wire.