Schemas
JSON Schemas (draft 2020-12) for every file and record the formats define.
Each schema's $id is https://scient.ing/ns/schemas/<file>, and schemas refer to each other by those names, so a validator that loads the whole folder resolves every reference.
Which schema for which file
| Topic | Schemas |
|---|---|
| Shared definitions | common.schema.json: hashes, IDs, keys, addresses, times, decimals, boxes, licenses, signatures, evidence, quotes. |
| A package | manifest.schema.json, document.schema.json, node.schema.json, runs.schema.json, witnesses.schema.json, provenance.schema.json, page.schema.json, location.schema.json, reference.schema.json, id-entry.schema.json, correction.schema.json, receipt.schema.json, revocation.schema.json, roster.schema.json, suspect.schema.json, mathml.schema.json |
| Pointing into documents | anchor.schema.json |
| Rights | rights.schema.json, policy.schema.json, stages.schema.json, backend.schema.json, profile.schema.json, stamps.schema.json |
| Review | qa-report.schema.json |
| Annotation and teaching | layer.schema.json, annotation.schema.json, exercise.schema.json, submission.schema.json, grade.schema.json |
| Data | dataset.schema.json, value-anchor.schema.json, digitization.schema.json, view.schema.json |
| Teams and drafts | project.schema.json, snapshot.schema.json, draft-ids.schema.json |
A record that travels on its own carries a format such as scienting-anchor/1; registry/formats.json maps each format to its schema.
Validating
With the jsonschema package (4.18 or later):
import json, pathlib
from jsonschema import Draft202012Validator
from referencing import Registry, Resource
schemas = {p.name: json.loads(p.read_text()) for p in pathlib.Path("schemas").glob("*.json")}
registry = Registry().with_resources((s["$id"], Resource.from_contents(s)) for s in schemas.values())
validator = Draft202012Validator(schemas["anchor.schema.json"], registry=registry)
validator.validate(json.load(open("fixtures/records/anchor-span.json")))
Any draft 2020-12 validator works the same way; python3 tools/check.py validates every fixture with the repository's own validator and, when installed, with jsonschema too.
What a schema does not check
A schema checks shape: required properties, types, patterns, enumerations. It cannot check that a hash recomputes, that a node's children are allowed, that a correction's ID derives from its content, or that a receipt's signature verifies. Those are the rules of spec/22-conformance.md, each with an ID in registry/rules.json.
Writing schemas
The schemas use only the keywords listed in spec/22-conformance.md, and their patterns avoid \d, \w, \s, \b and lookbehind, so that validators in every language read them alike.
Optional properties are omitted rather than set to null, except where a schema says a property is nullable.