Specifications
The contracts are JSON Schemas (draft 2020-12) and normative documents. They are the source of truth: Yggdrasil’s own code is generated from them and tested against shared fixtures in TypeScript and Python. Version 1 was frozen on 4 October 2026 (tag specs-v1.0.0); release 1.1.0 (tag specs-v1.1.0, 7 October 2026) adds YGG1 1.1, which binds encrypted data to its context and processors’ keys and outputs to the real project. Breaking changes need a new major version; additions are minor releases.
Start with the contracts overview: identifiers, versioning, conventions, show-if conditions, encrypted manifest text and the rules every validator must check beyond JSON Schema.
Documents
Section titled “Documents”| Document | What it defines |
|---|---|
| YGG1 encryption format | Object keys, the chunked asset container, small objects, HPKE key sealing, identity keys, key bundles, project epochs, the signed project log and safety codes. With test vectors. |
| Processor HTTP API v1 | How a processor registers, claims jobs, holds leases, reads its inputs, uploads outputs and posts results. |
| Volume geometry v1 | One canonical geometry per volumetric series from DICOM, NIfTI and NRRD, the coordinate spaces of selectors, and the labelmap layout. |
Schemas
Section titled “Schemas”| Contract | Schema |
|---|---|
| Project manifest | manifest/v1 |
| Annotation envelope (visible to the server) | annotation/envelope-v1 |
| Annotation payload (encrypted body and selector) | annotation/payload-v1 |
| Selectors | annotation/selectors-v1 |
| Annotation types: body and task configuration | types/ |
| Modality descriptor | modality/descriptor-v1 |
| Processor descriptor | processor/descriptor-v1 |
| Plugin package (the plugin catalog) | plugin/package-v1 |
| Processor API payloads | processor/api/ |
| Volume geometry and labelmaps | geometry/volume-v1 |
| De-identification receipt | deid/receipt-v1 |
| Entity metadata (the encrypted metadata of patients, studies, series and assets) | data/entity-meta-v1 |
| In-page guide tours | guides/tour-v1 |
| Shared definitions | common/v1 |
A series’ metadata also holds its pictures’ calibrations and display transforms (crop, mirror and rotation): viewers apply a transform to the camera, while the stored image and every shape stay in the original pixels.
Starter project manifests are in templates/.
Plugins
Section titled “Plugins”Modalities and annotation types are plugins; an installation adds others from its plugin catalog. A modality plugin ingests, de-identifies, normalises and displays one kind of data, and declares itself with a modality descriptor. An annotation type defines a body schema and a task configuration schema. The built-in annotation types of version 1:
| Type | Body |
|---|---|
ygg.classification.single@1, ygg.classification.multi@1 |
One or several options |
ygg.classification.boolean@1 |
Yes or no |
ygg.classification.ordinal@1 |
One level of an ordered scale |
ygg.value.text@1, ygg.value.number@1 |
Free text, or a number with an optional unit |
ygg.geometry.point@1, ygg.geometry.box@1, ygg.geometry.polygon@1 |
A labelled shape, with its geometry in the selector |
ygg.segmentation.labelmap@1 |
A labelmap asset and its segments |
Measurement types carry a labelled shape and the values the reader’s client measured on it, with their units: ygg.geometry.line@1, ygg.geometry.polyline@1, ygg.geometry.angle@1, ygg.geometry.cobb@1, ygg.geometry.bidirectional@1, ygg.geometry.ellipse@1, ygg.geometry.freehand@1, ygg.geometry.probe@1 and ygg.geometry.oriented-box@1.
Temporal types mark a video’s frames (frames counted from 0 in presentation order, with their times): ygg.temporal.interval@1 holds a reader’s labelled runs of frames (phases, events) and ygg.temporal.frame-tag@1 their tagged single frames. ygg.temporal.phases@1 (since 1.40.0) splits a video or a signal recording into consecutive phases: each marker (a label, a time in seconds and, on a video, a frame) starts a phase that lasts until the next one. Shapes on a video name their frame in the pixel selector, and since 1.41.0 may name a track, the object they follow (keyframes of one track are interpolated between, and held after the last until one marked outside), and a task’s frameRate sets which frames readers annotate, for example one per second.
Signal types mark a recording (ECG, EEG) in seconds from its first sample: ygg.signal.interval@1 holds a reader’s labelled time ranges (waves, beats, seizures) and ygg.signal.event@1 their labelled times (R peaks, spikes), each optionally on some channels only.
Reference types point outside the answer: ygg.ontology.term@1 picks terms of the project’s code list (SNOMED CT, RadLex or its own codes) and ygg.attachment.file@1 attaches files such as report PDFs, each stored as an encrypted asset that is never parsed.
Validating documents
Section titled “Validating documents”- TypeScript: the
@yggdrasil/specspackage exportsvalidate(id, data)and the generated types. - Python: load every schema into a
referencing.Registrykeyed by$idand validate withjsonschema.Draft202012Validator. - Anything else: any draft 2020-12 validator with ECMA-262 regular expressions.