Specification scope: Core with the Import, Units, and Validation companion specifications.
A telemetry project may need units and validation without alternate names or conditional composition. Copying the extended meta-schema would leave that project maintaining a private copy of definitions it does not intend to change.
Composition records the selection without a manually maintained copy of the parent definitions. Import processing copies the selected base definitions, selects the offered add-ins, and publishes the result under a new identifier. A processor resolves that URI to find the vocabulary permitted by the project.
Start with the extended meta-schema
The extended v0 meta-schema advertises optional bundles through $offers. A
derived meta-schema references extended with $schema, imports its definitions,
and selects bundles with $uses.
This complete custom meta-schema enables import because composition itself uses
$import, then adds units and validation. It deliberately leaves out alternate
names and conditional composition.
{
"$schema": "https://json-structure.org/meta/extended/v0/#",
"$id": "https://schemas.example.com/meta/telemetry/v0/#",
"$import": "https://json-structure.org/meta/extended/v0/#",
"$uses": [
"JSONStructureImport",
"JSONStructureUnits",
"JSONStructureValidation"
],
"$root": "#/definitions/SchemaDocument",
"name": "TelemetrySchemaDialect"
}
This is the same composition form used by the published validation meta-schema:
the new document imports the parent and reuses its SchemaDocument root. The
selected add-ins augment the imported type model rather than requiring copied
definitions.
$schema and $import do different jobs. $schema says which meta-schema
checks this custom meta-schema. $import brings the parent’s definitions into
the new document so #/definitions/SchemaDocument resolves locally after
processing. Treating $schema as an implicit import would make the document
depend on processor behavior it never declares.
Schemas name the dialect they obey
A consuming schema points $schema at the custom meta-schema. It also records
the optional feature bundles it uses at its own root, following the add-in
contract exposed through the composed meta-schema.
{
"$schema": "https://schemas.example.com/meta/telemetry/v0/#",
"$id": "https://schemas.example.com/telemetry/pressure-reading",
"name": "PressureReadingSchema",
"$uses": [
"JSONStructureUnits",
"JSONStructureValidation"
],
"$root": "#/definitions/PressureReading",
"definitions": {
"PressureReading": {
"name": "PressureReading",
"type": "object",
"properties": {
"sensorId": {
"type": "string",
"pattern": "^P-[A-Z0-9]{6}$"
},
"pressure": {
"type": "double",
"unit": "kPa",
"minimum": 80,
"maximum": 120
}
},
"required": ["sensorId", "pressure"],
"additionalProperties": false
}
}
}
An application instance then points to that schema:
{
"$schema": "https://schemas.example.com/telemetry/pressure-reading",
"sensorId": "P-3A91F2",
"pressure": 101.325
}
The schema has no altnames, oneOf, or if, and its declared dialect never
admitted those vocabularies. An unknown keyword is therefore an error, not an
invitation for a processor to guess whether it is an annotation, a typo, or a
private extension.
The URI identifies the vocabulary
The custom meta-schema’s $id is not decorative branding. It gives the exact
combination a stable identity. Schema registries can cache it, generators can
select handlers from it, and validators can reject documents that use keywords
outside it.
The URI identifies a narrower language than “extended JSON Structure.” Telemetry schemas may describe units and impose validation policy; they do not thereby pick up every other extension in the extended vocabulary.
The present drafts contain one inconsistency: core says $uses is
instance-only while its own SchemaDocument meta-definition allows the
property, and the published meta-schemas rely on root-level $uses. A schema or
meta-schema is the instance at this layer, so the examples follow the shipped
meta-schema behavior. Processors that interpret instance documents as
application data only will reject the project’s published meta-schemas.
Fork the language when you intend to change its rules. Selecting vocabulary that the language already offers is composition, and giving that selection a URI makes it resolvable. A copied meta-schema would only disguise that simpler choice and create another document to keep in sync.