From b717731a720eac46bc5e190ef106d0fc2c97e0a2 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Fri, 26 Sep 2025 16:42:30 +0200 Subject: [PATCH 01/19] init rfc-8 --- rfc/8/index.md | 1104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1104 insertions(+) create mode 100644 rfc/8/index.md diff --git a/rfc/8/index.md b/rfc/8/index.md new file mode 100644 index 00000000..5b0e82eb --- /dev/null +++ b/rfc/8/index.md @@ -0,0 +1,1104 @@ +# RFC-8: Collections + +Adding groupings of images and other objects to OME-Zarr. + +## Status + +This proposal is very early. Status: D1 + +| Name | GitHub Handle | Institution | Date | Status | +| --------- | ------------- | ----------- | ---------- | ------------------------------------- | +| Norman Rzepka | [normanrz](https://github.com/normanrz) | scalable minds | 2024-11-20 | Author | +| Eric Perlman | [perlman](https://github.com/perlman) | Yikes LLC | 2024-11-20 | Author | +| Joel Lüthi | [jluethi](https://github.com/jluethi) | BioVisionCenter Zurich | 2024-11-20 | Author | +| Christian Tischer | [tischi](https://github.com/tischi) | EMBL | 2025-02-01 | Author | +| Matthew Hartley | [matthewh-ebi](https://github.com/matthewh-ebi) | EMBL-EBI | 2025-05-05 | Author | + +## Overview + +This proposal adds a new "collection" concept to OME-Zarr. + +- Collections can be used to group together images, including segmentations, prediction maps and other derived images as well as other data types ("nodes"). +- Collections can be nested. +- Collections can have metadata attached. Within collections, nodes can also have metadata, which complements or overrides the nodes' own metadata. +- Nodes within collections are referenced by paths instead of relying on a file system hierarchy. Paths may also be absolute and point to remote storage. + +This proposal does not aim to invent new concepts, but unify approaches that the community has already adopted, in a standards-compliant and extensible manner. + + + +## Background + +### The Why +* **Viewing**. Many viewers need to visualize multiple images at the same time. There is no generic way of defining this group of images. +* **Discoverability**. Zarr doesn't have a way of discovering groups within a group, which requires file system scans to discover images within a group. +* **Unifying concepts**. OME-Zarr has a few collection types already, e.g. high-content screening, bioformats2raw.layout. This is an opportunity to unify them. +* **Extensibility**. OME-Zarr does not have representations for adding other objects, e.g. tables, meshes, to a hierarchy. Through new metadata, collections offers a path to add new object types. +* **Metadata**. Collections allow to attach metadata to images or other objects without altering the original object (think: overriding). While this proposal does not specify the semantics of such metadata, it provides means for storing them. + +### User stories + +#### 1. Visualize multiple images at once +Several viewers are capable of visualizing multiple images, that can map to a common coordinate space, at once. Examples are Webknossos, Neuroglancer, MoBIE and OMERO.figure. All of these tools have developed their own JSON-based metadata to combine multiple images in a collection, see "[Prior art and references](#prior-art-and-references)". In addition to mere path references of the images, this metadata also contains information about coordinate transforms and rendering settings. + +As there is no standard-compliant way in OME-Zarr to describe multiple images in one entity, users need to copy multiple links to interoperably visualize multiple images. + +#### 2. m:n segmentations +While OME-Zarr has support for attaching labels to images, the support is not sufficient for many use cases. +There are multiple label images that can be attached to a single image. This is a 1:n relationship. However, m:n relationships would be desired because labels might be related to multiple images. Examples for that are: +- Multiple correlated images express the same feature that is being labeled. +- Channels are stored in multiple images instead of in the same image. + +Additionally, there are other types of derived images, such as prediction maps, which cannot currently be represented by OME-Zarr. In comparison to label maps, where each voxel is assigned a discrete ID, prediction maps have a channel per segmentation class (or similar) and each voxel is assigned a probability or other continuous value. + +#### 3. Shallow copies of images with segmentations +Many workflow engines operate by taking input images and producing output images. In many cases, it is desired to keep the input images unchanged. +Let's assume the example of a pixel classification task. This task would take an OME-Zarr image as input and produce a prediction map. To express the relationship between input image and output prediction, the task could create a collection that contains the prediction and links to the image (i.e. shallow copy). The output collection could then be used to visualize both at the same time. This is applicable to a wide variety of workflow tasks with the result that the outputs of each task can be visualized or further processed independent of other tasks. + +``` +├─ input_image.zarr +│ ├─ zarr.json # OME-Zarr multiscale +│ ├─ 0 +│ └─ ... +└─ output_collection.zarr + │ # includes collection metadata and link to "../input_image.zarr" + ├─ zarr.json + └─ prediction.zarr + ├─ zarr.json # OME-Zarr multiscale + ├─ 0 + └─ ... +``` + +Examples for such workflow systems: +- [Voxelytics](https://voxelytics.com) +- [Fractal](https://fractal-analytics-platform.github.io/) +- [Nextfow](https://www.nextflow.io/) + +#### 4. Overriding transforms + + + +* TODO for Eric + * John can help if desired + +#### 5. High Content Screening (HCS) plates +OME-Zarr high content screening plates are a current example of a very narrowly defined type of collection. They allow to group OME-Zarr images in multiple hierarchy levels: A plate contains wells, which are organized as row folders with column subfolders in each. Each well folder can contain a number of images. There is defined metadata about which wells are in a plate and about which images are in a well at the different hierarchy levels, typically with some additional optional metadata like the acquisitions that exist in a plate and which image belongs to which acquisition. +This hierarchy is very useful for typical experiments where researchers imaged a multi-well plate. Multiple viewers like MoBIE, napari & ViZarr support displaying the different wells arranged in the plate format given the OME-Zarr HCS metadata, thus avoiding the need for tool-specific metadata and showing the benefits of such collection concepts. +The current HCS spec also has its limitations: It has a strict definition of potential metadata fields at the plate and well level. There are multiple areas where it would be interesting to extend this spec. There are [ongoing discussions](https://github.com/ome/ngff/pull/137) about whether individual microscope fields of view (ie. well) should be stored as individual OME-Zarr images or as a single OME-Zarr image. In that context, it is unclear how one would provide metadata about the individual images in a well and what a viewer should do with them. For example, depending on whether an OME-Zarr image in a well is an individual field of view of a given acquisition, a second acquisition of the same region in a plate or an image derived from a given processing operation, the optimal viewer default on whether to show or not show multiple images at once will vary. A flexible metadata field like `attributes` would allow us to better define such image metadata. A more flexible HCS collection system could also allow to provide advanced metadata on well positions [when wells have different sizes](https://github.com/ome/ome-zarr-py/issues/240) or address other edge-cases in the current HCS configuration. + + +#### 6. Image Archive +* TODO for Matthew + +#### 7. Rendering settings +Viewers, such as Webknossos, Neuroglancer, MoBIE and OMERO.figure, are capable of visualizing multiple OME-Zarr images ("layers") in a view. +To share such a view, metadata serialization is required that contains not only links to the images, but also attached metadata of the rendering state. +The rendering state of a collection might contain locations, rotation angles, coordinate systems as well as rendering state of individual layers. +The rendering state of layers might contain pixel transformations (e.g. min/max scaling, colors, shaders), coordinate transformation overrides, visibility settings. + +Some of these rendering state attributes might be compatible across implementations, but others might not. +This proposal does not intend to provide a specification for the rendering state itself, but provide metadata containers to store such viewer-specific state. + + +#### 8. Grouping together remote images + +When building upon images that have been published by others, it might be useful to create virtual groupings of multiple remotely stored images. +For example, a lab might create automatic segmentations of a large image that has been published by another lab. +While the segmentation would now be published on its own, it could still be published with a link to the original images so that viewers are able to show the segmentation as an overlay on the original data. + +#### 9. Adding other datatypes to images +When processing images in the OME-Zarr format, a diversity of derived data like segmentation, probability maps, meshes, tables and other formats can be generated. This proposal does not intend to provide a specification to all these datatypes, but to define the metadata of how related data in Zarr or other formats can be linked to OME-Zarr images. + +Because there is already a specification for labels in the spec, the label definition is broadened by this spec. For other datatypes like tables, [past proposals](https://github.com/ome/ngff/pull/64) have focused on how tables can be serialised to OME-Zarr. As these proposals did not proceed to become part of the OME-Zarr spec, different implementers have built their own sub-specs for tables (see e.g. the [ngio table definition](https://fractal-analytics-platform.github.io/ngio/v0.3.2/table_specs/overview/) coming from the Fractal project or the [label table](https://mobie.github.io/specs/mobie_spec.html#table-data) in MoBIE). While future proposals and extensions may define datatypes like tables more strictly, this proposal offers a general way to make such additional data types discoverable. + +#### 10. Gallery / grid views + +It is useful to visualise similar images in a grid view where all images are visible as "thumbnails", which in the case of OME-Zarr can simply be the lowest resolution version of the data. Like this, users can have an overview of all the data and can then decide to "zoom in" on some datasets to explore them in higher resolution. + +Implementations of this concept include: +- [Zarrcade](https://github.com/JaneliaSciComp/zarrcade) +- [BioFile Finder](https://bff.allencell.org/) +- [MoBIE grid views](https://mobie.github.io/tutorials/image_grids_and_tables.html) +- [OME2024 NGFF challenge](https://ome.github.io/ome2024-ngff-challenge/) + +For example, [this table](https://docs.google.com/spreadsheets/d/1t5xB0p0zd2-a6ynV-JAuLJqs-mg-pFFikhfmQGZwRpI/edit?usp=sharing) defines a MoBIE grid view of three OpenOrganelle vEM images along with label images of mitochondria segmenation. It can be opened in MoBIE via the "Open Simple Collection Table" menu entry: + +![Clipboard](https://hackmd.io/_uploads/HklvOUrDexg.jpg) + + + + + +## Proposal + + + +This proposal adds collections to the OME-Zarr specification. +"Collections" are groupings of "nodes". +Nodes either reference OME-Zarr images (multiscales) or collections. +Nested collections can also be inlined in the metadata. +Nodes reference images or collections that are stored locally relative to the collection or remotely (using URLs). +Arbitrary user or implementation metadata may be added to collections or nodes, which is an opportunity to add metadata that is only valid for a node in the context of a collection (e.g. rendering settings). +Images may be added as nodes to multiple collections. + + +### Metadata + +This RFC defines two main objects for OME-Zarr: `Collection`, `CollectionNode`. + +#### `Collection` keys + +* `"node_type"` (required). Value must be `"collection"`. +* `"nodes"` (required). Value must be an array of `CollectionNode` or `Collection` objects. +* `"name"` (required). Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. +* `"attributes"` (optional). Value must be a dictionary. See below. + +A `Collection` object may be used as the root object of the `ome` key, in which case a `version` key, as defined in previous spec versions, is also required. + +#### `CollectionNode` keys + +* `"node_type"` (required). Must be a valid node type string, which is currently either `"multiscale"` or `"collection"`. Future RFCs might add more node types. + - `"multiscale"` references a node that represents an OME-Zarr multiscale image. + - `"collection"` references a node that is a collection itself, i.e. a nested collection. +* `"name"` (required). Value must be a non-empty string. The name must be unique within the parent collection. It should be a string that be matches `[a-zA-Z0-9-_.]+`. +* `"path"` (required). Value must be a string containing a path (see below). +* `"attributes"` (optional). Value must be a dictionary. See below. + + +#### Attributes + +Collections and CollectionNodes have `attributes` keys that can be populated with arbitrary JSON metadata. +A primary use case for the attributes is the specialization of collections and nodes through additional metadata. + +There are unprefixed and prefixed top-level keys in the `attributes` dictionary. +Unprefixed keys are reserved. +Changes to or additions of unprefixed keys are expected to be made through the RFC process. +Custom keys SHOULD be namespaced by a prefix (separated by `:`). +Prefixes SHOULD be registered in a central registry by individuals or organizations (e.g. dev teams), which will be a Github repository under the `ome` organization. +Registration of a prefix claim maintainership for that prefix. +The registry also provides a discoverable location for specification of the keys. +The `ome:` prefix is reserved. + +We envision that popular implementations will claim prefixes to customize their metadata, e.g. `mobie:`, `neuroglancer:`, `fractal:`, `webknossos:`. + +Custom-prefixed keys can also be used to add additional sub-keys or behavior to existing attributes. +This can be thought of as a way of achieving inheritance. +For example, the `well` keys could be specialized by a `fractal:well` key that adds additional sub-keys with altering behavior. +It is out-of-scope of this RFC to fully define the inheritance behavior. +That is left for specializing attributes to define on a case-by-case basis and may be standardized in a future RFC. + +While attributes are effective for creating specialized collections and nodes, implementations are not required to parse them. +Implementations are encouraged to provide graceful fallback strategies for specialized collections and nodes that are not understood by the implementation. +Strategies could include falling back to basic collection semantics, providing selector screens, or rendering nodes with default settings. + + +### Examples + +#### Simple example +```json +{ + "ome": { + "version": "0.x", + "node_type": "collection", + "name": "jrc_hela-1", + "nodes": [{ + "name": "raw", + "node_type": "multiscale", // image or collection + "path": "./raw", // a relative or absolute path + "attributes": { + "example-viewer:settings": { + "isDisabled": true + }, + "other-viewer:voxelType": "intensities" + ... // arbitrary user-defined metadata + }, + }, { + "name": "..", + "node_type": "collection", + "path": "./nested_collection.json" + }, ... ], + "attributes": { + ... + } + } +} +``` + +##### Grid view JSON example + +A gallery view could also be represented within the proposed collection JSON as shown in the below example. + +Note that the grid view is modelled here as a collection of collections, where the collection at each grid position includes the raw EM image and the mitochondria segmentation label mask image. + +Also note some MoBIE specific attributes: + +- `"mobie:grid": "true"` specifies that the data should be laid out in a grid. +- `"mobie:voxelType": "intensities"` (or `"labels"`) specifies the voxel data type; in the future, we would propose that this information is encoded within the OME-Zarr images themselves, such that this attribute could be omitted. + + +```json +{ + "ome": { + "version": "0.x", + "node_type": "collection", + "name": "openorganelle-mito-gallery", + "attributes": { + "mobie:grid": "true" + }, + "nodes": [ + { + "name": "jrc_hela-3", + "node_type": "collection", + "nodes": [ + { + "node_type": "multiscale", + "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_hela-3/jrc_hela-3.zarr/em/fibsem-uint16", + "attributes": { + "mobie:voxelType": "intensities" + } + }, + { + "node_type": "multiscale", + "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_hela-3/jrc_hela-3.zarr/labels/mito_seg", + "attributes": { + "mobie:voxelType": "labels" + } + } + ] + }, + { + "name": "jrc_macrophage-2", + "node_type": "collection", + "nodes": [ + { + "node_type": "multiscale", + "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_macrophage-2/jrc_macrophage-2.zarr/em/fibsem-uint16", + "attributes": { + "mobie:voxelType": "intensities" + } + }, + { + "node_type": "multiscale", + "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_macrophage-2/jrc_macrophage-2.zarr/labels/mito_seg", + "attributes": { + "mobie:voxelType": "labels" + } + } + ] + }, + { + "name": "jrc_jurkat-1", + "node_type": "collection", + "nodes": [ + { + "node_type": "multiscale", + "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_jurkat-1/jrc_jurkat-1.zarr/em/fibsem-uint16", + "attributes": { + "mobie:voxelType": "intensities" + } + }, + { + "node_type": "multiscale", + "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_jurkat-1/jrc_jurkat-1.zarr/labels/mito_seg", + "attributes": { + "mobie:voxelType": "labels" + } + } + ] + } + ] + } +} +``` + +### Label maps and other derived images + +#### Example + + +### HCS metadata + +High content screening data is commonnly composed of multiple multiscale images ("well") that are arranged in a grid on a "plate". +Additional metadata for organizing the wells on a plate is introduced here. + +Open questions Joel: +How do we relate derived data to existing data best in the HCS context without becoming a nesting nightmare? + +We have a well with X images. All of the images can have labels and tables. And maybe one would use the collection spec to allow for labels that apply to multiple images in the same well or tables that apply to multiple images. + +How do we represent images in wells that can optionally be related to labels and optionally be related to tables? Does the well always contain a nested collection (we called that “the OME-Zarr container”, e.g. the object that knows about the image data, label data and related table data like ROI tables in our work so far)? Or is it sometimes nested, sometimes not? + +#### Example +```json +{ + "ome": { + "version": "0.x", + "node_type": "collection", + "name": "hcs-plate-001", + "attributes": { + "plate": { + "acquisitions": [...], + "columns": [...], + "rows": [...], + } + } + "nodes": [ + { + "node_type": "collection", + "name": "well A01", + "attributes": { + "well": { + "column": 1, + "row": "A", + "acquisition": 0 + } + } + "nodes": [ + { + "node_type": "multiscale", + "name": "well-001-001", + "path": "./A/01/001.img.zarr", + }, + { + "node_type": "multiscale", + "name": "A01_0_nuclei", + "path": "/full/path/A/01/nuclei.img.zarr", + "attributes": { + "label": {} + } + }, + ... + ] + }, + ...] + } +} +``` + +### bioformats2raw.layout metadata + +#### Example + +### Attaching coordinate transforms + +Coordinate transforms as defined in RFC-5 + +### Where is this collection metadata stored? + +Collection metadata may be stored either in the `ome` key of the `attributes` container in a `zarr.json` file of a Zarr group. +This is particularly useful for defining the nodes that are stored within a Zarr group. However, there is no limitation to only reference nodes within the Zarr group. + +#### Example +```json +{ + "zarr_format": 3, + "node_type": "group", + "attributes": { + "ome": { + "version": "0.x", + "node_type": "collection", + "name": "zarr.json-example", + "nodes": [{ + "node_type": "multiscale", + "name": "image1", + "path": "./image1.img.zarr" + }, ...] + } + } +} +``` + +Collection metadata may also be stored in a standalone json files that are stored in arbitrary locations and have a file name ending in `.json`. +Here, the metadata is stored in the `ome` key of the root object. +Standalone files are useful for persisting groupings of images that may or may not be stored on in the same folder hierarchy. + +### Example +```json +{ + "ome": { + "version": "0.x", + "node_type": "collection", + "name": "standalone-example", + "nodes": [{ + "node_type": "multiscale", + "path": "https://example.com/image1.img.zarr" + }, ...] + } +} +``` + +### Paths + +This proposal uses paths are referencing nodes of collections. +This paths can be one of the following types: + +- **Relative paths.** + To reference nodes that are on the same file system namespace as the json file describing the collection, relative paths may be used. + Relative paths are interpreted relative to the json file describing the collection. + Relative paths follow the relative path notation defined in [IETF RFC1808](https://datatracker.ietf.org/doc/html/rfc1808). + Briefly, `.` and `..` are used to navigate the hierarchy and the hierarchy is separated by `/`. + Relative paths may be used for data stored on traditional file systems as well as other storage protocols, such as HTTP or S3. +- **Absolute file paths.** + On traditional file systems, absolute paths may be used. + Please note that absolute file paths are generally not portable across operating systems or file systems. + - On Windows systems, paths commonly begin with a drive letter followed by `:\`. The folder hierarchy is separated by `\`. UNC paths are also permissible. + - On POSIX-like systems, paths commonly start with a `/` and the folder hierarchy is separated by `/`. +- **HTTP(S) URLs.** + To reference nodes that are stored remotely, URLs with the `http` or `https` scheme may be used. + URLs follow the notation defined in [IETF RFC1738](https://datatracker.ietf.org/doc/html/rfc1738). + +Future RFCs may propose additional paths, such as S3 URLs or chained paths (e.g. for referencing files within a zip file). +In any case, implementations may impose access restrictions on any type of paths. + + +## Requirements + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [IETF RFC 2119](https://tools.ietf.org/html/rfc2119) + + + + +## Stakeholders + + + +- Visualization developers +- Data management developers +- Image Archives +- Workflow developers + +### Socialization +* [Github issue](https://github.com/ome/ngff/issues/31) +* OME-NGFF community meeting April 2024 + * https://docs.google.com/presentation/d/1ANsNdCchmwWR1grhg5-hSrWH5nyPz2QSFYToF56PVc4/edit#slide=id.g2c639a0285f_0_40 +* OME meeting 2024 in Dundee +* I2K 2024 in Milan +* OME-NGFF hackathon Zurich + * https://hackmd.io/OeY6A-ysQQu_NZuG7a-cXQ +* Volume EM GRC Barcelona 2025 +* OME-NGFF community meeting June 2025 + +## Implementation + +This RFC has not been implemented yet. + +However, several visualization tools already have support for showing multiple images in the same view, see "Prior art and references". +Adopting this new metadata format is reasonable. + +It is also expected that programming libraries will support this new metadata format to construct and inspect collections. + + + + +## Drawbacks, risks, alternatives, and unknowns +This RFC adds backwards and forwards incompatible changes, which presents additional complexity to implementations and users. + +Defining a custom format instead of reusing existing validated formats introduces risk or design errors. + + + +## Abandoned Ideas + +### RO Crate +Instead of defining a custom collection format for OME-Zarr, existing collection formats, such as RO Crate, could be utilized. + +Research Object Crate ("RO Crate") is a standard format that utilizes JSON-LD to define collections of research artifacts as well as their relationships and other metadata. +Utilizing RO Crate for OME-Zarr collections would allow to build upon an existing standard that has been validated in the field. +Additionally, it would allow to easily integrate with other research artifacts, such as publications, talks, protocols, etc. + +RO Crate imposes very strict requirements around its metadata. +Every key in a metadata object needs to be backed by a well-defined schema. +While very precise, this presents burdens for adding user-defined metadata. + +All the metadata in RO Crate is normalized and hierarchies or relationships are maintained via IDs. +This is a common approach in database systems design. +However, it leads to metadata files which are very hard to read by humans. +This practically necessitates the use of libraries to inspect the metadata, which contradicts a design guideline of Zarr and OME-Zarr. + +This RFC proposes adopting a simpler collection specification for OME-Zarr. +RO Crate can still be used alongside collections or images to define metadata and integrate with other research objects. + +### Extensions + +TODO: We now use (registered) attributes, because it is more flexible. In particular, it makes clear that attributes are not required for implementations to understand, albeit potentially resulting in poorer UX. + + + +## Prior art and references + +### Initial Github issue + +Initial discussions started here: https://github.com/ome/ngff/issues/31 + +### Neuroglancer JSON + +See https://neuroglancer-docs.web.app/json/api/index.html + +
+ JSON example +Shortened version from https://fafb-ffn1.storage.googleapis.com/landing.html +```json +{ + "dimensions": { + "x": [ + 4e-9, + "m" + ], + "y": [ + 4e-9, + "m" + ], + "z": [ + 4e-8, + "m" + ] + }, + "position": [ + 109421.8984375, + 41044.6796875, + 5417 + ], + "crossSectionScale": 2.1875, + "projectionOrientation": [ + -0.08939177542924881, + -0.9848012924194336, + -0.07470247149467468, + 0.12882165610790253 + ], + "projectionScale": 27773.019357116023, + "layers": [ + { + "type": "image", + "source": { + "url": "precomputed://gs://neuroglancer-fafb-data/fafb_v14/fafb_v14_orig" + }, + "blend": "default", + "name": "fafb_v14", + "visible": false + }, + { + "type": "image", + "source": { + "url": "precomputed://gs://neuroglancer-fafb-data/fafb_v14/fafb_v14_clahe" + }, + "blend": "default", + "name": "fafb_v14_clahe" + }, + { + "type": "segmentation", + "source": { + "url": "precomputed://gs://fafb-ffn1-20190805/segmentation" + }, + "segments": [ + "710435991" + ], + "skeletonRendering": { + "mode2d": "lines_and_points", + "mode3d": "lines" + }, + "name": "fafb-ffn1-20190805" + }, + ... + ], + "showAxisLines": false, + "showSlices": false, + "layout": "xy-3d" +} +``` +
+ + +### MoBIE collections + +The MoBIE collection table allows users to specify a collection of images and segmentations (label mask images) and configure their rendering. + +Each row in the table corresponds to one (single-channel) image or segmentation. + +To open multi-channel images the image URI must be added several times and a `channel` column must be added to specify which channel to load. + +One can specify an affine transformation for each image. + +One can configure a grid layout to render multiple images side-by-side. + +The same image can be opened multiple times, with different rendering settings or different transformations. + +- [Example table](https://github.com/mobie/mobie-viewer-fiji/blob/main/src/test/resources/collections/blobs-grid-table.txt) +- [More example tables](https://github.com/mobie/mobie-viewer-fiji/blob/main/src/test/resources/collections) +- [More details](https://mobie.github.io/tutorials/mobie_collection_table.html) + + +### Webknossos datasource-properties.json +Webknossos uses a JSON format to define "datasets", which is a non-nestable collection of images with some metadata attached. It mirrors some of the OME-Zarr multiscale metadata for compatibility reasons. + +
+JSON example +```json +{ + "id": { + "name": "l4_sample3", + "team": "" + }, + "dataLayers": [ + { + "name": "color", + "category": "color", + "boundingBox": { + "topLeft": [ + 3072, + 3072, + 512 + ], + "width": 1024, + "height": 1024, + "depth": 1024 + }, + "elementClass": "uint8", + "mags": [ + { + "mag": [ + 1, + 1, + 1 + ], + "path": "./color/1", + "axisOrder": { + "x": 1, + "y": 2, + "z": 3, + "c": 0 + }, + "channelIndex": 0 + }, + { + "mag": [ + 2, + 2, + 1 + ], + "path": "./color/2-2-1", + "axisOrder": { + "x": 1, + "y": 2, + "z": 3, + "c": 0 + }, + "channelIndex": 0 + } + ], + "numChannels": 1, + "dataFormat": "zarr" + }, + { + "name": "segmentation", + "boundingBox": { + "topLeft": [ + 3072, + 3072, + 512 + ], + "width": 1024, + "height": 1024, + "depth": 1024 + }, + "elementClass": "uint32", + "mags": [ + { + "mag": [ + 1, + 1, + 1 + ], + "path": "./segmentation/1", + "axisOrder": { + "x": 1, + "y": 2, + "z": 3, + "c": 0 + }, + "channelIndex": 0 + }, + { + "mag": [ + 2, + 2, + 1 + ], + "path": "./segmentation/2-2-1", + "axisOrder": { + "x": 1, + "y": 2, + "z": 3, + "c": 0 + }, + "channelIndex": 0 + } + ], + "largestSegmentId": 2504697, + "numChannels": 1, + "dataFormat": "zarr", + "category": "segmentation" + } + ], + "scale": { + "factor": [ + 11.24, + 11.24, + 28 + ], + "unit": "nanometer" + } +} +``` +
+ +### STAC +from the Geo Community https://stacindex.org/ https://stacspec.org/ + +### BIDS +https://direct.mit.edu/imag/article/doi/10.1162/imag_a_00103/119672/The-Past-Present-and-Future-of-the-Brain-Imaging + +https://github.com/bids-standard/bids-specification-pdf-releases/blob/1.10.0/bids-spec.pdf + +People worked on getting ome-zarr into BIDS +https://github.com/bids-standard/bids-examples/tree/master/micr_XPCTzarr + +### OMERO.figure +OMERO.figure uses a JSON file to specify the layout and rendering settings for images, as well as some info on page(s) layout. Until now, these images are hosted and rendered by OMERO, but support for OME-Zarr images is underway at https://github.com/ome/omero-figure/pull/619. Here, the OMERO Image ID is replaced by an OME-Zarr URL and rendering happens in the browser. See [the demo](https://will-moore.github.io/omero-figure/?file=https://gist.githubusercontent.com/will-moore/fe0e260544b46af6e1e523b288fc85bc/raw/30547e61d4d8753ef0016f0a70435f1aafb43c2f/OMERO.figure_NGFF_demo.json). + +The OMERO.figure json format is [described here](https://github.com/ome/omero-figure/blob/master/docs/figure_file_format.rst#json-format). + + +JSON example +Shortened version from https://gist.githubusercontent.com/will-moore/fe0e260544b46af6e1e523b288fc85bc/raw/30547e61d4d8753ef0016f0a70435f1aafb43c2f/OMERO.figure_NGFF_demo.json +```json +{ + "panels": [ + { + "x": 32.776939633609516, + "y": 299.60384546911166, + "width": 157, + "height": 160.5839416058394, + "zoom": 100, + "dx": 0, + "dy": 0, + "labels": [], + "deltaT": [], + "rotation": 0, + "selected": false, + "pixel_size_x_symbol": "µm", + "pixel_size_x_unit": "MICROMETER", + "rotation_symbol": "°", + "max_export_dpi": 1000, + "vertical_flip": false, + "horizontal_flip": false, + "imageId": "https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0062A/6001240.zarr", + "name": "6001240.zarr", + "sizeZ": 236, + "theZ": 118, + "sizeT": 1, + "theT": 0, + "channels": [ + { + "active": true, + "coefficient": 1, + "color": "0000FF", + "family": "linear", + "inverted": false, + "label": "LaminB1", + "window": { + "end": 1500, + "max": 65535, + "min": 0, + "start": 0 + } + }, + { + "active": true, + "coefficient": 1, + "color": "FFFF00", + "family": "linear", + "inverted": false, + "label": "Dapi", + "window": { + "end": 1500, + "max": 65535, + "min": 0, + "start": 0 + } + } + ], + "orig_width": 271, + "orig_height": 275, + "pixelsType": "uint16", + "zarr": { + // consolidate zarr metadata here + } + } + ] +} + + + + +## Future possibilities + +Collections is a possibility for extending OME-Zarr in a backwards-compatible manner. + +Future additions include: + +- Additional node types, such as tables, meshes +- Additional path types, such as S3 URLs + +Within the collections proposal, there are also opportunities for standardizing further metadata: + +- Rendering state +- Expressing relationships between nodes in a collection + +Future work: + +- Defining formal mechanism for extensions + + + +## Performance + +- Duplicated metadata? +- Multiple requests to collect metadata? + + + +## Compatibility + +### Backwards compatible +This proposal deprecates the labels, HCS and bioformats2raw.layout parts of the OME-Zarr specification. +The core multiscale metadata is unchanged and remains backwards compatible. +Existing images can be wrapped in collections with additional metadata attached. + +### Forward compatible +Existing implementations need to be updated to able to understand the new collection objects. + + + +## Testing + +As part of the changes to the OME-Zarr specification, JSON schema files will be provided that can be used to validate collections metadata. +Additional link checkers can be used to verify the existance and validity of nodes. + + + +## Tutorials and Examples + + + +## Additional considerations + + + +### Security + +- Paths? + + + + + +### UI/UX + + \ No newline at end of file From 049164bf74871c3411173bf83599502980af16cb Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Fri, 26 Sep 2025 16:53:01 +0200 Subject: [PATCH 02/19] iteration --- rfc/8/assets/mobie_grid_view.jpg | Bin 0 -> 56794 bytes rfc/8/index.md | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 rfc/8/assets/mobie_grid_view.jpg diff --git a/rfc/8/assets/mobie_grid_view.jpg b/rfc/8/assets/mobie_grid_view.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1dc490e44b05bf714a829d2c53079233841e0f60 GIT binary patch literal 56794 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∨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 r<>iNRQNv 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

JSON example Shortened version from https://fafb-ffn1.storage.googleapis.com/landing.html -```json + +
 {
   "dimensions": {
     "x": [
@@ -692,7 +693,7 @@ Shortened version from https://fafb-ffn1.storage.googleapis.com/landing.html
   "showSlices": false,
   "layout": "xy-3d"
 }
-```
+
@@ -720,7 +721,7 @@ Webknossos uses a JSON format to define "datasets", which is a non-nestable coll
JSON example -```json +
 {
   "id": {
     "name": "l4_sample3",
@@ -836,7 +837,7 @@ Webknossos uses a JSON format to define "datasets", which is a non-nestable coll
     "unit": "nanometer"
   }
 }
-```
+
### STAC @@ -855,10 +856,11 @@ OMERO.figure uses a JSON file to specify the layout and rendering settings for i The OMERO.figure json format is [described here](https://github.com/ome/omero-figure/blob/master/docs/figure_file_format.rst#json-format). - +
JSON example Shortened version from https://gist.githubusercontent.com/will-moore/fe0e260544b46af6e1e523b288fc85bc/raw/30547e61d4d8753ef0016f0a70435f1aafb43c2f/OMERO.figure_NGFF_demo.json -```json + +
 {
     "panels": [
         {
@@ -924,6 +926,7 @@ Shortened version from https://gist.githubusercontent.com/will-moore/fe0e260544b
         }
     ]
 }
+
+ ## Overview This proposal adds a new "collection" concept to OME-Zarr. @@ -98,7 +107,9 @@ The current HCS spec also has its limitations: It has a strict definition of pot #### 6. Image Archive -* TODO for Matthew +Data archives that support deposition and access to OME-Zarr formatted images have two primary use cases for collections of images. For the first, users submitting data to deposition databases need ways to aggregate collections of images in their data upload structure, and do so in a way that supports describing how those images relate (e.g. parts of the same acquisition series, plate/well data as mentioned above). This can then be parsed during data submission, and used to create appropriate database records. + +Secondly, when providing outgoing access to data, archives want to provide groupings of images that allow compatibility with data exploration and visualisation tools. Given the increasingly rich ecosystem of these tools (mentioned across these use cases, and including grid views, segmentations, multiple images and plate/well data) standardisation is necessary to avoid the need to produce view/exploration schema for each tool. #### 7. Rendering settings Viewers, such as Webknossos, Neuroglancer, MoBIE and OMERO.figure, are capable of visualizing multiple OME-Zarr images ("layers") in a view. @@ -175,19 +186,19 @@ This RFC defines two main objects for OME-Zarr: `Collection`, `CollectionNode`. #### `Collection` keys -* `"node_type"` (required). Value must be `"collection"`. +* `"type"` (required). Value must be `"collection"`. * `"nodes"` (required). Value must be an array of `CollectionNode` or `Collection` objects. -* `"name"` (required). Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. +* `"name"` (required). Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within one collections JSON file. * `"attributes"` (optional). Value must be a dictionary. See below. A `Collection` object may be used as the root object of the `ome` key, in which case a `version` key, as defined in previous spec versions, is also required. #### `CollectionNode` keys -* `"node_type"` (required). Must be a valid node type string, which is currently either `"multiscale"` or `"collection"`. Future RFCs might add more node types. +* `"type"` (required). Must be a valid node type string, which is currently either `"multiscale"` or `"collection"`. Future RFCs might add more node types. - `"multiscale"` references a node that represents an OME-Zarr multiscale image. - `"collection"` references a node that is a collection itself, i.e. a nested collection. -* `"name"` (required). Value must be a non-empty string. The name must be unique within the parent collection. It should be a string that be matches `[a-zA-Z0-9-_.]+`. +* `"name"` (required). Value must be a non-empty string. The name must be unique within the parent collection. It should be a string that be matches `[a-zA-Z0-9-_.]+`. Must be unique within one collections JSON file. * `"path"` (required). Value must be a string containing a path (see below). * `"attributes"` (optional). Value must be a dictionary. See below. @@ -226,11 +237,11 @@ Strategies could include falling back to basic collection semantics, providing s { "ome": { "version": "0.x", - "node_type": "collection", + "type": "collection", "name": "jrc_hela-1", "nodes": [{ "name": "raw", - "node_type": "multiscale", // image or collection + "type": "multiscale", // image or collection "path": "./raw", // a relative or absolute path "attributes": { "example-viewer:settings": { @@ -241,7 +252,7 @@ Strategies could include falling back to basic collection semantics, providing s }, }, { "name": "..", - "node_type": "collection", + "type": "collection", "path": "./nested_collection.json" }, ... ], "attributes": { @@ -267,7 +278,7 @@ Also note some MoBIE specific attributes: { "ome": { "version": "0.x", - "node_type": "collection", + "type": "collection", "name": "openorganelle-mito-gallery", "attributes": { "mobie:grid": "true" @@ -275,17 +286,17 @@ Also note some MoBIE specific attributes: "nodes": [ { "name": "jrc_hela-3", - "node_type": "collection", + "type": "collection", "nodes": [ { - "node_type": "multiscale", + "type": "multiscale", "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_hela-3/jrc_hela-3.zarr/em/fibsem-uint16", "attributes": { "mobie:voxelType": "intensities" } }, { - "node_type": "multiscale", + "type": "multiscale", "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_hela-3/jrc_hela-3.zarr/labels/mito_seg", "attributes": { "mobie:voxelType": "labels" @@ -295,17 +306,17 @@ Also note some MoBIE specific attributes: }, { "name": "jrc_macrophage-2", - "node_type": "collection", + "type": "collection", "nodes": [ { - "node_type": "multiscale", + "type": "multiscale", "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_macrophage-2/jrc_macrophage-2.zarr/em/fibsem-uint16", "attributes": { "mobie:voxelType": "intensities" } }, { - "node_type": "multiscale", + "type": "multiscale", "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_macrophage-2/jrc_macrophage-2.zarr/labels/mito_seg", "attributes": { "mobie:voxelType": "labels" @@ -315,17 +326,17 @@ Also note some MoBIE specific attributes: }, { "name": "jrc_jurkat-1", - "node_type": "collection", + "type": "collection", "nodes": [ { - "node_type": "multiscale", + "type": "multiscale", "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_jurkat-1/jrc_jurkat-1.zarr/em/fibsem-uint16", "attributes": { "mobie:voxelType": "intensities" } }, { - "node_type": "multiscale", + "type": "multiscale", "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_jurkat-1/jrc_jurkat-1.zarr/labels/mito_seg", "attributes": { "mobie:voxelType": "labels" @@ -345,7 +356,7 @@ Also note some MoBIE specific attributes: ### HCS metadata -High content screening data is commonnly composed of multiple multiscale images ("well") that are arranged in a grid on a "plate". +High content screening data is commonly composed of multiple multiscale images ("well") that are arranged in a grid on a "plate". Additional metadata for organizing the wells on a plate is introduced here. Open questions Joel: @@ -360,7 +371,7 @@ How do we represent images in wells that can optionally be related to labels and { "ome": { "version": "0.x", - "node_type": "collection", + "type": "collection", "name": "hcs-plate-001", "attributes": { "plate": { @@ -371,7 +382,7 @@ How do we represent images in wells that can optionally be related to labels and } "nodes": [ { - "node_type": "collection", + "type": "collection", "name": "well A01", "attributes": { "well": { @@ -382,12 +393,12 @@ How do we represent images in wells that can optionally be related to labels and } "nodes": [ { - "node_type": "multiscale", + "type": "multiscale", "name": "well-001-001", "path": "./A/01/001.img.zarr", }, { - "node_type": "multiscale", + "type": "multiscale", "name": "A01_0_nuclei", "path": "/full/path/A/01/nuclei.img.zarr", "attributes": { @@ -423,10 +434,10 @@ This is particularly useful for defining the nodes that are stored within a Zarr "attributes": { "ome": { "version": "0.x", - "node_type": "collection", + "type": "collection", "name": "zarr.json-example", "nodes": [{ - "node_type": "multiscale", + "type": "multiscale", "name": "image1", "path": "./image1.img.zarr" }, ...] @@ -444,10 +455,10 @@ Standalone files are useful for persisting groupings of images that may or may n { "ome": { "version": "0.x", - "node_type": "collection", + "type": "collection", "name": "standalone-example", "nodes": [{ - "node_type": "multiscale", + "type": "multiscale", "path": "https://example.com/image1.img.zarr" }, ...] } @@ -623,9 +634,8 @@ Initial discussions started here: https://github.com/ome/ngff/issues/31 See https://neuroglancer-docs.web.app/json/api/index.html
- JSON example +JSON example Shortened version from https://fafb-ffn1.storage.googleapis.com/landing.html -
 {
   "dimensions": {
@@ -859,7 +869,6 @@ The OMERO.figure json format is [described here](https://github.com/ome/omero-fi
 
JSON example Shortened version from https://gist.githubusercontent.com/will-moore/fe0e260544b46af6e1e523b288fc85bc/raw/30547e61d4d8753ef0016f0a70435f1aafb43c2f/OMERO.figure_NGFF_demo.json -
 {
     "panels": [

From 591b1f511a9656b40334c9eba528c83d47831dc8 Mon Sep 17 00:00:00 2001
From: Norman Rzepka 
Date: Mon, 29 Sep 2025 14:06:15 +0200
Subject: [PATCH 04/19] lorenzo

---
 rfc/8/index.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/rfc/8/index.md b/rfc/8/index.md
index e16ff04a..05d40fa9 100644
--- a/rfc/8/index.md
+++ b/rfc/8/index.md
@@ -11,6 +11,7 @@ This proposal is early. Status: D1
 | Norman Rzepka | [normanrz](https://github.com/normanrz) | scalable minds | 2024-11-20 | Author |
 | Eric Perlman | [perlman](https://github.com/perlman) | Yikes LLC | 2024-11-20 | Author |
 | Joel Lüthi | [jluethi](https://github.com/jluethi) | BioVisionCenter Zurich | 2024-11-20 | Author |
+| Lorenzo Cerrone | [lorenzocerrone](https://github.com/lorenzocerrone) | BioVisionCenter Zurich | 2024-11-20 | Author |
 | Christian Tischer | [tischi](https://github.com/tischi) | EMBL | 2025-02-01 | Author |
 | Matthew Hartley | [matthewh-ebi](https://github.com/matthewh-ebi) |  EMBL-EBI | 2025-05-05 | Author |
 

From 662d510c2e80bbe94b6c993ca7b86de8d2034463 Mon Sep 17 00:00:00 2001
From: Norman Rzepka 
Date: Mon, 29 Sep 2025 14:23:00 +0200
Subject: [PATCH 05/19] codespell

---
 rfc/8/index.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/rfc/8/index.md b/rfc/8/index.md
index 05d40fa9..785d7b65 100644
--- a/rfc/8/index.md
+++ b/rfc/8/index.md
@@ -143,7 +143,7 @@ Implementations of this concept include:
 - [MoBIE grid views](https://mobie.github.io/tutorials/image_grids_and_tables.html)
 - [OME2024 NGFF challenge](https://ome.github.io/ome2024-ngff-challenge/)
 
-For example, [this table](https://docs.google.com/spreadsheets/d/1t5xB0p0zd2-a6ynV-JAuLJqs-mg-pFFikhfmQGZwRpI/edit?usp=sharing) defines a MoBIE grid view of three OpenOrganelle vEM images along with label images of mitochondria segmenation. It can be opened in MoBIE via the "Open Simple Collection Table" menu entry: 
+For example, [this table](https://docs.google.com/spreadsheets/d/1t5xB0p0zd2-a6ynV-JAuLJqs-mg-pFFikhfmQGZwRpI/edit?usp=sharing) defines a MoBIE grid view of three OpenOrganelle vEM images along with label images of mitochondria segmentation. It can be opened in MoBIE via the "Open Simple Collection Table" menu entry: 
 
 ![MoBIE grid view](./assets/mobie_grid_view.jpg)
 
@@ -1043,7 +1043,7 @@ How are implementations expected to handle these changes?
 ## Testing
 
 As part of the changes to the OME-Zarr specification, JSON schema files will be provided that can be used to validate collections metadata.
-Additional link checkers can be used to verify the existance and validity of nodes.
+Additional link checkers can be used to verify the existence and validity of nodes.
 
 
 
 * TODO for Eric
-    * John can help if desired
+* CLEM
 
 #### 5. High Content Screening (HCS) plates
 OME-Zarr high content screening plates are a current example of a very narrowly defined type of collection. They allow to group OME-Zarr images in multiple hierarchy levels: A plate contains wells, which are organized as row folders with column subfolders in each. Each well folder can contain a number of images. There is defined metadata about which wells are in a plate and about which images are in a well at the different hierarchy levels, typically with some additional optional metadata like the acquisitions that exist in a plate and which image belongs to which acquisition.
@@ -1138,4 +1138,4 @@ feel like the rest of the ecosystem. Further, if the breaking changes are
 intolerable or there is a way to make a change while preserving compatibility,
 that should be explored.
 
--->
\ No newline at end of file
+-->

From 7c7a1ec505b6d2861d535d6cbc4b4195794d6439 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Tue, 28 Oct 2025 12:57:33 +0100
Subject: [PATCH 09/19] propose interface between rfc5 and rfc8

---
 rfc/8/index.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/rfc/8/index.md b/rfc/8/index.md
index bd9b8f6c..2ea31889 100644
--- a/rfc/8/index.md
+++ b/rfc/8/index.md
@@ -102,6 +102,7 @@ Examples for such workflow systems:
 * CLEM
 
 #### 5. High Content Screening (HCS) plates
+(hcs-plates-collection)=
 OME-Zarr high content screening plates are a current example of a very narrowly defined type of collection. They allow to group OME-Zarr images in multiple hierarchy levels: A plate contains wells, which are organized as row folders with column subfolders in each. Each well folder can contain a number of images. There is defined metadata about which wells are in a plate and about which images are in a well at the different hierarchy levels, typically with some additional optional metadata like the acquisitions that exist in a plate and which image belongs to which acquisition.
 This hierarchy is very useful for typical experiments where researchers imaged a multi-well plate. Multiple viewers like MoBIE, napari & ViZarr support displaying the different wells arranged in the plate format given the OME-Zarr HCS metadata, thus avoiding the need for tool-specific metadata and showing the benefits of such collection concepts.
 The current HCS spec also has its limitations: It has a strict definition of potential metadata fields at the plate and well level. There are multiple areas where it would be interesting to extend this spec. There are [ongoing discussions](https://github.com/ome/ngff/pull/137) about whether individual microscope fields of view (ie. well) should be stored as individual OME-Zarr images or as a single OME-Zarr image. In that context, it is unclear how one would provide metadata about the individual images in a well and what a viewer should do with them. For example, depending on whether an OME-Zarr image in a well is an individual field of view of a given acquisition, a second acquisition of the same region in a plate or an image derived from a given processing operation, the optimal viewer default on whether to show or not show multiple images at once will vary. A flexible metadata field like `attributes` would allow us to better define such image metadata. A more flexible HCS collection system could also allow to provide advanced metadata on well positions [when wells have different sizes](https://github.com/ome/ome-zarr-py/issues/240) or address other edge-cases in the current HCS configuration.
@@ -147,6 +148,14 @@ For example, [this table](https://docs.google.com/spreadsheets/d/1t5xB0p0zd2-a6y
 
 ![MoBIE grid view](./assets/mobie_grid_view.jpg)
 
+#### 11. Coordinate transformations
+
+Similar to [HCS plates](hcs-plates-collection), coordinate transformations as defined by RFC5 define a narrow case of image collections.
+In this case, images are part of a collection if they share a common coordinate space that is defined by coordinate systems and coordinate transformations.
+Since the relationships between images are already defined in a graph like schema as proposed in this RFC,
+the transformations metadata can be represented as a specialized collection with coordinate systems and transformations as attributes of the collection and nodes.
+In a way, coordinate transformations and systems simply become a subset of the more general collection concept.
+
 
 
 
+Several applications in microscopy and other imaging domains involve the acquisition of images
+of the same object from different angles or with different imaging modalities.
+Examples of such applications are (among others) the following:
+- Correlative light and electron microscopy (CLEM): In this case,
+  a sample is examined with both electron and light microscopy,
+  both of which feature their own sets of spatial dimensions.
+  A set of coordinate transformations is used to map between the different images.
+- Multiview lightsheet: For this application,
+  lightsheet microscopes acquire multiple views of the same object from different angles.
+  A set of coordinate transformations is used to map between the different views.
+- Multimodal medical imaging: Different imaging modalities (e.g., CT, MRI, PET, etc),
+  are often used either in conjunction or at different timepoints to observe the same object or anatomical structure. 
+
+Such applications require the storage of collections of images and their mutual relationships,
+the metadata for which has already been defined by RFC5 (Coordinate Transformations in OME-NGFF).
+In the context of RFC5, images are part of a collection if they share a common coordinate space
+that is defined by coordinate systems and coordinate transformations.
+Since the relationships between images are already defined
+in a graph-like schema as proposed in this RFC,
+the transformations metadata can be represented as a specialized collection
+with coordinate systems and transformations as attributes of the collection and nodes.
+In a way, coordinate transformations and systems simply become a subset of the more general collection concept.
 
-* TODO for Eric
-* CLEM
 
 #### 5. High Content Screening (HCS) plates
 (hcs-plates-collection)=
@@ -149,14 +165,6 @@ For example, [this table](https://docs.google.com/spreadsheets/d/1t5xB0p0zd2-a6y
 
 ![MoBIE grid view](./assets/mobie_grid_view.jpg)
 
-#### 11. Coordinate transformations
-
-Similar to [HCS plates](hcs-plates-collection), coordinate transformations as defined by RFC5 define a narrow case of image collections.
-In this case, images are part of a collection if they share a common coordinate space that is defined by coordinate systems and coordinate transformations.
-Since the relationships between images are already defined in a graph like schema as proposed in this RFC,
-the transformations metadata can be represented as a specialized collection with coordinate systems and transformations as attributes of the collection and nodes.
-In a way, coordinate transformations and systems simply become a subset of the more general collection concept.
-
 
 
 
 
+### TODO
+- Path objects
+- Rework the multiscale node; including inlining multiscales
+- Attribute merging
+- Topology, can a collection reference itself
+- Names unique per collection instead of file and define references ("../" or UUID)
+- Extension points (extract from attributes section)
+
+
 ## Overview
 
 This proposal adds a new "collection" concept to OME-Zarr.
@@ -108,8 +117,8 @@ Examples of such applications are (among others) the following:
   are often used either in conjunction or at different timepoints to observe the same object or anatomical structure. 
 
 Such applications require the storage of collections of images and their mutual relationships,
-the metadata for which has already been defined by RFC5 (Coordinate Transformations in OME-NGFF).
-In the context of RFC5, images are part of a collection if they share a common coordinate space
+the metadata for which has already been defined by RFC-5 (Coordinate Transformations in OME-NGFF).
+In the context of RFC-5, images are part of a collection if they share a common coordinate space
 that is defined by coordinate systems and coordinate transformations.
 Since the relationships between images are already defined
 in a graph-like schema as proposed in this RFC,
@@ -192,61 +201,142 @@ solution, but for details further sections will be used.
 
 This proposal adds collections to the OME-Zarr specification.
 "Collections" are groupings of "nodes".
-Nodes either reference OME-Zarr images (multiscales) or collections.
-Nested collections can also be inlined in the metadata.
+Nodes either reference OME-Zarr images (multiscales, singlescales) or collections.
+Nested collections and multiscales can be inlined in the metadata.
 Nodes reference images or collections that are stored locally relative to the collection or remotely (using URLs).
 Arbitrary user or implementation metadata may be added to collections or nodes, which is an opportunity to add metadata that is only valid for a node in the context of a collection (e.g. rendering settings).
 Images may be added as nodes to multiple collections.
 
+### Goals
+
+- Define a mechanism for grouping images into (hierarchical) collections
+- Define a mechanism for referencing components of a collection (nodes, coordinate systems etc) internally and externally
+- Add extensibility to collections for user/implementation-specific metadata and new node types
+- Make a new home for HCS, bioformats2raw.layout and labels metadata
+- Incorporate coordinate systems and transformations
+
 
 ### Metadata
 
+#### `Node`
+
 This RFC defines a basic interface for a OME-Zarr metadata object, which we name `Node`.
-Objects that implement `Node` must have the following fields:
+Objects that implement `Node` have the following fields:
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
 | `"type"` | string | yes | Identifies the type of the node |
-| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within one collections JSON file. |
+| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
+| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within the enclosing collection. |
 | `"attributes"` | object | no | [See attributes section](#attributes) |
 
 The `type` field of a `Node` defines the additional fields, if any, it has. 
-This RFC proposed two Node types: `Collection` and `Multiscale`.
+This RFC proposed two Node types: `Collection`, `Multiscale` and `Singlescale`.
 Future RFCs might add more Node types, including custom Node types.
 
+A Node object may be used as the root object of the `ome` key, in which case a `version` key, as defined in previous spec versions, is also required.
+Non-root Node objects SHOULD not have `version` field and MUST NOT have a different `version` value than the root Node.
+
 #### `Collection` Node
 
 References a Node that is a collection of Nodes. 
-Collections can be nested.
+Collections MAY be nested.
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
 | `"type"` | string | yes | Value must be `"collection"`. |
+| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
+| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within the enclosing collection. |
 | `"nodes"` | array | no | Value must be an array of `Node` objects. |
-| `"path"` | string | no | Value must be a string containing a path. [See paths section](#paths) |
-| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within one collections JSON file. |
+| `"path"` | object | no | Value must be a `Path` object. |
 | `"attributes"` | object | no | Value must be a dictionary. [See attributes section](#attributes). |
 
-Either `"nodes"` or `"path"` must be present, but not both.
-
-A `Collection` object may be used as the root object of the `ome` key, in which case a `version` key, as defined in previous spec versions, is also required.
-Non-root `Collection` objects SHOULD not have `version` field and MUST NOT have a different `version` value than the root `Collection`.
+Either `"nodes"` or `"path"` MUST be present, but not both.
 
 #### `Multiscale` Node
 
 References a Node that represents an OME-Zarr multiscale image.
+This new interface replaces the multiscale metadata defined in the previous versions of the OME-Zarr specification.
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
 | `"type"` | string | yes | Value must be `"multiscale"`. |
+| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
 | `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within one collections JSON file. |
-| `"path"` | string | yes | Value must be a string containing a path. [See paths section](#paths) |
+| `"nodes"` | array | no | Value must be an array of `Singlescale` objects. |
+| `"path"` | object | no | Value must be a `Path` object. |
 | `"attributes"` | string | no | Value must be a dictionary. [See attributes section](#attributes). |
 
+Either `"nodes"` or `"path"` MUST be present, but not both.
+
+
+#### `Singlescale` Node
+
+References a Node that represents one resolution representation of an OME-Zarr multiscale image.
+This new interface replaces the multiscale metadata defined in the previous versions of the OME-Zarr specification.
+
+| Field | Type | Required? | Notes |
+| - | - | - | - |
+| `"type"` | string | yes | Value must be `"multiscale"`. |
+| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
+| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within one collections JSON file. |
+| `"path"` | object | yes | Value must be a `Path` object. |
+| `"attributes"` | string | yes | Value must be a dictionary. [See attributes section](#attributes). |
+
+Singlescale nodes MUST have a `"coordinateTransformations"` key in their attributes which conforms to the [coordinate transformations](#coordinate-transformations) specification and only contains "scale" and "translate" transformations.
+
+#### Paths
+
+This new interface replaces the paths defined in the previous versions of the OME-Zarr specification.
+
+| Field | Type | Required? | Notes |
+| - | - | - | - |
+| `"type"` | string | yes | Value must be valid path type. |
+| `"path"` | string | yes | Value must be a string containing a path. See below. |
+
+The path `"type"` defines how the path is interpreted. Currently, the `"zarr"` and `"json"` types are supported. 
+The `"zarr"` type is used for paths that reference nodes in a Zarr array or group. Implementations need to append `zarr.json` to the path to access the metadata of the referenced node.
+The `"json"` type is used for paths that reference nodes in a JSON file.
+
+This `path` strings can be one of the following types:
+
+- **Relative paths.**
+  To reference nodes that are on the same file system namespace as the json file describing the collection, relative paths may be used.
+  Relative paths are interpreted relative to the json file describing the collection.
+  Relative paths follow the relative path notation defined in [IETF RFC1808](https://datatracker.ietf.org/doc/html/rfc1808).
+  Briefly, `.` and `..` are used to navigate the hierarchy and the hierarchy is separated by `/`.
+  Relative paths may be used for data stored on traditional file systems as well as other storage protocols, such as HTTP or S3.
+- **Absolute file paths.**
+  On traditional file systems, absolute paths may be used.
+  Please note that absolute file paths are generally not portable across operating systems or file systems.
+  - On Windows systems, paths commonly begin with a drive letter followed by `:\`. The folder hierarchy is separated by `\`. UNC paths are also permissible.
+  - On POSIX-like systems, paths commonly start with a `/` and the folder hierarchy is separated by `/`.
+- **HTTP(S) URLs.** 
+  To reference nodes that are stored remotely, URLs with the `http` or `https` scheme may be used.
+  URLs follow the notation defined in [IETF RFC1738](https://datatracker.ietf.org/doc/html/rfc1738).
+
+Future RFCs may propose additional paths, such as S3 URLs or chained paths (e.g. for referencing files within a zip file).
+In any case, implementations may impose access restrictions on any type of paths.
+
+
+#### References
+
+Objects that are being referenced MUST have an `"id"` key.
+
+The reference can be a string with an ID for referencing objects within the same JSON document.
+For more complex references, the reference can be an object with the following fields:
+
+| Field | Type | Required? | Notes |
+| - | - | - | - |
+| `"id"` | string | yes | Value must be a string that matches `[a-zA-Z0-9-_.]+`. |
+| `"path"` | object | no | Value must be a `Path` object. |
+
+For external references, the `"path"` key MUST be present.
+
 
 #### Attributes
 
-Collections and CollectionNodes have `attributes` keys that can be populated with arbitrary JSON metadata. 
+Nodes have `attributes` keys that can be populated with arbitrary JSON metadata. 
 A primary use case for the attributes is the specialization of collections and nodes through additional metadata.
 
 There are unprefixed and prefixed top-level keys in the `attributes` dictionary.
@@ -270,34 +360,31 @@ While attributes are effective for creating specialized collections and nodes, i
 Implementations are encouraged to provide graceful fallback strategies for specialized collections and nodes that are not understood by the implementation. 
 Strategies could include falling back to basic collection semantics, providing selector screens, or rendering nodes with default settings.
 
+Unprefixed attributes that are defined as part of this RFC are:
+- `coordinateSystems`
+- `coordinateTransformations`
+- `labels`, as well as `label-value` and `color` in label attributes
+- `plate` and `well`
 
-#### Paths
+### Extensibility
 
-This proposal uses paths are referencing nodes of collections.
-This paths can be one of the following types:
+Adding collections to OME-Zarr provides an opportunity to define extension points.
 
-- **Relative paths.**
-  To reference nodes that are on the same file system namespace as the json file describing the collection, relative paths may be used.
-  Relative paths are interpreted relative to the json file describing the collection.
-  Relative paths follow the relative path notation defined in [IETF RFC1808](https://datatracker.ietf.org/doc/html/rfc1808).
-  Briefly, `.` and `..` are used to navigate the hierarchy and the hierarchy is separated by `/`.
-  Relative paths may be used for data stored on traditional file systems as well as other storage protocols, such as HTTP or S3.
-- **Absolute file paths.**
-  On traditional file systems, absolute paths may be used.
-  Please note that absolute file paths are generally not portable across operating systems or file systems.
-  - On Windows systems, paths commonly begin with a drive letter followed by `:\`. The folder hierarchy is separated by `\`. UNC paths are also permissible.
-  - On POSIX-like systems, paths commonly start with a `/` and the folder hierarchy is separated by `/`.
-- **HTTP(S) URLs.** 
-  To reference nodes that are stored remotely, URLs with the `http` or `https` scheme may be used.
-  URLs follow the notation defined in [IETF RFC1738](https://datatracker.ietf.org/doc/html/rfc1738).
+TODO: Explain naming scheme, similar to attributes (prefixed vs unprefixed)
 
-Future RFCs may propose additional paths, such as S3 URLs or chained paths (e.g. for referencing files within a zip file).
-In any case, implementations may impose access restrictions on any type of paths.
+TODO: List and explain Extension points
 
+- Node types
+- Attributes
+- Path types
+- Coordinate transforms
+- Coordinate system axes
 
 
 ### Examples
 
+See more examples at https://github.com/normanrz/ngff-rfc8-collection-examples/.
+
 #### Simple example
 ```jsonc
 {
@@ -307,19 +394,24 @@ In any case, implementations may impose access restrictions on any type of paths
         "name": "jrc_hela-1",
         "nodes": [{
             "name": "raw",
-            "type": "multiscale", // image or collection
-            "path": "./raw", // a relative or absolute path
+            "type": "multiscale",
+            "path": {
+              "type": "zarr",
+              "path": "./raw", // a relative or absolute path
+            },
             "attributes": {    
                 "example-viewer:settings": {
                     "isDisabled": true
                 },
-                "other-viewer:voxelType": "intensities"
                 ... // arbitrary user-defined metadata
             },
         }, {
             "name": "..",
             "type": "collection",
-            "path": "./nested_collection.json"
+            "path": {
+              "type": "json",
+              "path": "./nested_collection.json"
+            }
         }, ... ],
         "attributes": {
             ...
@@ -328,7 +420,50 @@ In any case, implementations may impose access restrictions on any type of paths
 }
 ```
 
-##### Grid view JSON example
+
+#### Inlined multiscale
+```jsonc
+{
+    "ome": {
+        "version": "0.x",
+        "type": "collection",
+        "name": "example",
+        "attributes": {
+            "coordinateSystems": [
+                {
+                  "id": "world",
+                  "name": "world",
+                  "axes": [...]
+                }
+            ]
+        },
+        "nodes": [{
+            "name": "raw",
+            "type": "multiscale",
+            "nodes": [{
+                "id": "raw_0",
+                "type": "singlescale",
+                "path": {
+                  "type": "zarr",
+                  "path": "./raw/0"
+                },
+                "attributes": {
+                  "coordinateTransformations": [
+                    {
+                      "type": "scale",
+                      "scale": [1, 1, 1],
+                      "input": "raw_0",
+                      "output": "world"
+                    }
+                  ]
+                }
+            }, ...]
+        }, ... ]
+    }
+}
+```
+
+#### Grid view JSON example
 
 A gallery view could also be represented within the proposed collection JSON as shown in the below example.
 
@@ -339,6 +474,7 @@ Also note some MoBIE specific attributes:
 - `"mobie:grid": "true"` specifies that the data should be laid out in a grid.
 - `"mobie:voxelType": "intensities"` (or `"labels"`) specifies the voxel data type; in the future, we would propose that this information is encoded within the OME-Zarr images themselves, such that this attribute could be omitted.
 
+TODO: Replace `mobie:voxelType` with `labels`
 
 ```jsonc
 {
@@ -356,14 +492,20 @@ Also note some MoBIE specific attributes:
                 "nodes": [
                     {
                         "type": "multiscale",
-                        "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_hela-3/jrc_hela-3.zarr/em/fibsem-uint16",
+                        "path": {
+                          "type": "zarr",
+                          "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_hela-3/jrc_hela-3.zarr/em/fibsem-uint16",
+                        },
                         "attributes": {
                             "mobie:voxelType": "intensities"
                         }
                     },
                     {
                         "type": "multiscale",
-                        "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_hela-3/jrc_hela-3.zarr/labels/mito_seg",
+                        "path": {
+                          "type": "zarr",
+                          "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_hela-3/jrc_hela-3.zarr/labels/mito_seg",
+                        },
                         "attributes": {
                             "mobie:voxelType": "labels"
                         }
@@ -376,14 +518,20 @@ Also note some MoBIE specific attributes:
                 "nodes": [
                     {
                         "type": "multiscale",
-                        "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_macrophage-2/jrc_macrophage-2.zarr/em/fibsem-uint16",
+                        "path": {
+                          "type": "zarr",
+                          "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_macrophage-2/jrc_macrophage-2.zarr/em/fibsem-uint16"
+                        },
                         "attributes": {
                             "mobie:voxelType": "intensities"
                         }
                     },
                     {
                         "type": "multiscale",
-                        "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_macrophage-2/jrc_macrophage-2.zarr/labels/mito_seg",
+                        "path": {
+                          "type": "zarr",
+                          "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_macrophage-2/jrc_macrophage-2.zarr/labels/mito_seg"
+                        },
                         "attributes": {
                             "mobie:voxelType": "labels"
                         }
@@ -396,14 +544,20 @@ Also note some MoBIE specific attributes:
                 "nodes": [
                     {
                         "type": "multiscale",
-                        "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_jurkat-1/jrc_jurkat-1.zarr/em/fibsem-uint16",
+                        "path": {
+                          "type": "zarr",
+                          "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_jurkat-1/jrc_jurkat-1.zarr/em/fibsem-uint16"
+                        },
                         "attributes": {
                             "mobie:voxelType": "intensities"
                         }
                     },
                     {
                         "type": "multiscale",
-                        "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_jurkat-1/jrc_jurkat-1.zarr/labels/mito_seg",
+                        "path": {
+                          "type": "zarr",
+                          "path": "https://janelia-cosem-datasets.s3.amazonaws.com/jrc_jurkat-1/jrc_jurkat-1.zarr/labels/mito_seg"
+                        },
                         "attributes": {
                             "mobie:voxelType": "labels"
                         }
@@ -417,14 +571,77 @@ Also note some MoBIE specific attributes:
 
 ### Label maps and other derived images
 
+Previous versions of the OME-Zarr specification defined a mechanism for associating label images with a singe multiscale image.
+This was achieved by using a `labels` Zarr group that had to be a direct child of the multiscale Zarr group with some specific metadata. 
+This proposal replaces this mechanism.
+
+To denote a multiscale image as a label map, the `labels` attribute SHOULD be present.
+If present, the value of the `labels` attribute MUST be an object with the following fields:
+
+| Field | Type | Required? | Notes |
+| - | - | - | - |
+| `"labelAttributes"` | array of objects | no | Attributes for individual labels. |
+| `"source"` | array of strings | no | An array with references to the source multiscales. |
+
+Because no fields are required, an empty object MAY be used.
+
+The previous `colors` and `properties` fields are now combined into a single `labelAttributes` field. The `rgba` field in the `colors` objects has been renamed to `color`.
+
+#### Label attributes
+
+The `colors` field is an array of objects with the following fields:
+
+| Field | Type | Required? | Notes |
+| - | - | - | - |
+| `"label-value"` | number | yes | Value must be the label value. |
+| `"color"` | array of number | no | Value must be a color in array format. | 
+
+If present, the `color` field MUST have an array with four integers between 0 and 255, inclusive. These integers represent the uint8 values of red, green, blue and alpha.
+
+Additional attributes MAY be added to the `attributes` field, following the attribute naming rules.
+
+
 #### Example
 
+```jsonc
+{
+    "ome": {
+        "version": "0.x",
+        "type": "collection",
+        "name": "label-example",
+        "attributes": { ... }
+        "nodes": [{
+            "id": "raw",
+            "name": "raw",
+            "type": "multiscale",
+            "nodes": [ ... ]
+        }, {
+            "name": "nuclei",
+            "type": "multiscale",
+            "nodes": [ ... ],
+            "attributes": {
+                "labels": {
+                    "source": [ "raw" ],
+                    "labelAttributes": [{
+                        "label-value": 1, // TODO: kebab-case is inconsistent
+                        "color": [ 255, 0, 0, 255 ]
+                    }, {
+                        "label-value": 2,
+                        "color": [ 0, 255, 0, 255 ]
+                    }]
+                }
+            }
+        }]
+    }
+}
+```
 
 ### HCS metadata
 
 High content screening data is commonly composed of multiple multiscale images ("well") that are arranged in a grid on a "plate".
 Additional metadata for organizing the wells on a plate is introduced here.
 
+TODO:
 Open questions Joel:
 How do we relate derived data to existing data best in the HCS context without becoming a nesting nightmare?
 
@@ -455,20 +672,26 @@ How do we represent images in wells that can optionally be related to labels and
                     "column": 1,
                     "row": "A",
                     "acquisition": 0
-                 }
+                }
             }
             "nodes": [
                 {
                     "type": "multiscale",
                     "name": "well-001-001",
-                    "path": "./A/01/001.img.zarr",
+                    "path": {
+                      "type": "zarr",
+                      "path": "./A/01/001.img.zarr"
+                    }
                 },
                 {
                     "type": "multiscale",
                     "name": "A01_0_nuclei",
-                    "path": "/full/path/A/01/nuclei.img.zarr",
+                    "path": {
+                      "type": "zarr",
+                      "path": "/full/path/A/01/nuclei.img.zarr"
+                    },
                     "attributes": {
-                        "label": {}
+                        "labels": {}
                     }
                 },
                 ...
@@ -481,14 +704,15 @@ How do we represent images in wells that can optionally be related to labels and
 
 ### bioformats2raw.layout metadata
 
-#### Example
+The bioformats2raw.layout metadata is replaced by this proposal.
+A series of images can now be represented as a collection of multiscale images.
 
-### Attaching coordinate transforms
+### Coordinate transforms
 
 Coordinate systems and transformations can be stored in three distinct locations:
 For single images, they can be stored in the `ome` key of the `attributes` container in a `zarr.json` file of the multiscales zarr group.
 Since these metadata are entirely self-contained, they are inherently compatible with the proposed collection metadata format.
-For collections of two or more images in a common coordinate system, RFC5 defines a parent-level metadata format.
+For collections of two or more images in a common coordinate system, RFC-5 defines a parent-level metadata format.
 In this layout, `coordinateTransformation` define relationships between different images or `coordinateSystems`:
 
 ```jsonc
@@ -497,16 +721,14 @@ In this layout, `coordinateTransformation` define relationships between differen
     {
       "type": "translation",
       "translation": [0, 0, 100],
-      "input": "image_1",  // can be path or coordinateSystem name
-      "output": "world"  // can be path or coordinateSystem name
+      "input": "image_1", // references collection node ID
+      "output": "world" // references coordinate system ID
     }
   ]
 }
 ```
 
-To avoid redundancy and ensure a strict mapping from coordinate transformations inputs/outputs to collection nodes,
-the input/output values of coordinate transformations could be allowed to reference collection node names.
-In this case, a collection node name could serve as a place holder for an image path.
+In a change from the previous specification, coordinate systems are referenced using the Reference interface, i.e. via IDs, and not via names.
 
 ```jsonc
 {
@@ -517,6 +739,7 @@ In this case, a collection node name could serve as a place holder for an image
     "attributes": {
       "coordinateSystems": [
         {
+          "id": "world",
           "name": "world",
           "axes": [...]
         }
@@ -525,33 +748,67 @@ In this case, a collection node name could serve as a place holder for an image
         {
           "type": "translation",
           "translation": [0, 0, 100],
-          "input": "tile_0",  // references collection node name
-          "output": "world"  // references coordinate system name
+          "input": "tile_0",  // references collection node ID
+          "output": "world"  // references coordinate system ID
         },
         {
           "type": "translation",
           "translation": [100, 0, 0],
-          "input": "tile_1",  // references collection node name
-          "output": "world"  // references coordinate system name
+          "input": "tile_1",  // references collection node ID
+          "output": "world"  // references coordinate system ID
         }
       ]
     },
     "nodes": [
       {
         "type": "multiscale",
+        "id": "tile_0",
         "name": "tile_0",
-        "path": "./tile_0.zarr",
+        "path": {
+          "type": "zarr",
+          "path": "./tile_0.zarr"
+        }
       }, 
       {
         "type": "multiscale",
+        "id": "tile_1",
         "name": "tile_1",
-        "path": "./tile_1.zarr",
+        "path": {
+          "type": "zarr",
+          "path": "./tile_1.zarr"
+        }
       },
     ]
   }
 }
 ```
 
+#### Coordinate systems
+
+The `coordinateSystems` attribute is an array of objects with the following fields:
+
+| Field | Type | Required? | Notes |
+| - | - | - | - |
+| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
+| `"name"` | string | yes | Value must be a non-empty string. As defined in RFC-5. |
+| `"axes"` | array of strings | yes | Value must be an array of axes, as defined in RFC-5. |
+
+
+#### Coordinate transforms
+
+The `coordinateTransformations` field is an array of objects with the following fields:
+
+| Field | Type | Required? | Notes |
+| - | - | - | - |
+| `"type"` | string | yes | Value must be a valid coordinate transform type, as defined in RFC-5. |
+| `"input"` | string | yes | Value must be a reference to the input coordinate system. |
+| `"output"` | string | yes | Value must be a reference to the input coordinate system. |
+
+Additional attributes MAY be added as required by the transform type.
+
+Please note that the semantics of the `input` and `output` fields are changed from by-name to by-reference (ID or reference object) compared to RFC-5
+
+
 ### Where is this collection metadata stored?
 
 Collection metadata may be stored either in the `ome` key of the `attributes` container in a `zarr.json` file of a Zarr group.
@@ -570,7 +827,10 @@ This is particularly useful for defining the nodes that are stored within a Zarr
             "nodes": [{
                 "type": "multiscale",
                 "name": "image1",
-                "path": "./image1.img.zarr"
+                "path": {
+                  "type": "zarr",
+                  "path": "./image1.img.zarr"  // reference to a Zarr group
+                }
             }, ...]
         }
     }
@@ -590,7 +850,10 @@ Standalone files are useful for persisting groupings of images that may or may n
         "name": "standalone-example",
         "nodes": [{
             "type": "multiscale",
-            "path": "https://example.com/image1.img.zarr"
+            "path": {
+              "type": "zarr",
+              "path": "https://example.com/image1.img.zarr"
+            }
         }, ...]
     }
 }

From cddcba213e3028069a418cc409ff3b6a3ab72ea5 Mon Sep 17 00:00:00 2001
From: Norman Rzepka 
Date: Fri, 16 Jan 2026 21:23:09 +0100
Subject: [PATCH 15/19] remove examples

---
 rfc/8/examples/README.md                      |   4 -
 rfc/8/examples/webknossos/custom-nodes.json   | 202 ------
 .../webknossos/inline-multiscale.json         | 580 ------------------
 3 files changed, 786 deletions(-)
 delete mode 100644 rfc/8/examples/README.md
 delete mode 100644 rfc/8/examples/webknossos/custom-nodes.json
 delete mode 100644 rfc/8/examples/webknossos/inline-multiscale.json

diff --git a/rfc/8/examples/README.md b/rfc/8/examples/README.md
deleted file mode 100644
index a04dbad7..00000000
--- a/rfc/8/examples/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# RFC-8 Examples
-
-* `webknossos/custom-nodes.json`: A typical Webknossos collection with EM data, affinity prediction and segmentation as well as some custom nodes for meshes, segment index, agglomeration and connectome.
-* `webknossos/inline-multiscale.json`: Same as `webknossos/custom-nodes.json` but with inlined multiscale metadata (non-standard, just as an experiment).
\ No newline at end of file
diff --git a/rfc/8/examples/webknossos/custom-nodes.json b/rfc/8/examples/webknossos/custom-nodes.json
deleted file mode 100644
index 6888cb7d..00000000
--- a/rfc/8/examples/webknossos/custom-nodes.json
+++ /dev/null
@@ -1,202 +0,0 @@
-{
-  "zarr_format": 3,
-  "node_type": "group",
-  "attributes": {
-    "ome": {
-      "version": "0.7",
-      "type": "collection",
-      "name": "l4dense_motta_et_al_dev_v2",
-      "attributes": {
-        "webknossos:rendering": {
-          "position": { "x": 2850, "y": 4318, "z": 1770 },
-          "zoom": 1.3,
-          "voxel_size": {
-            "factor": [11.239999771118164, 11.239999771118164, 28],
-            "unit": "nanometer"
-          }
-        }
-      },
-      "nodes": [
-        {
-          "type": "multiscale",
-          "name": "color",
-          "attributes": {
-            "webknossos:category": "color",
-            "webknossos:bounding_box": {
-              "topleft": { "x": 128, "y": 128, "z": 128 },
-              "size": { "x": 5445, "y": 8380, "z": 3285 }
-            },
-            "webknossos:data_type": "uint8"
-          },
-          "path": "/absolute/path/to/l4dense_motta_et_al_demo/color"
-        },
-        {
-          "type": "multiscale",
-          "name": "segmentation",
-          "attributes": {
-            "webknossos:category": "segmentation",
-            "webknossos:bounding_box": {
-              "topleft": { "x": 0, "y": 0, "z": 0 },
-              "size": { "x": 5632, "y": 8704, "z": 3584 }
-            },
-            "webknossos:data_type": "uint32",
-            "webknossos:values": { "max": 100000 }
-          },
-          "path": "./segmentation"
-        },
-        {
-          "type": "webknossos:mesh",
-          "name": "meshfile_4-4-2",
-          "path": "./segmentation/zarr/meshes/meshfile_4-4-2",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_5",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_5",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_10",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_10",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_15",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_15",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_20",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_20",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_25",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_25",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_30",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_30",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_35",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_35",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_40",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_40",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_45",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_45",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_50",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_50",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_55",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_55",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_60",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_60",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_65",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_65",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_70",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_70",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_75",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_75",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_80",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_80",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_85",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_85",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_90",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_90",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_95",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_95",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_100",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_100",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:segment_index",
-          "name": "segmentIndex",
-          "path": "./segmentation/zarr/segmentIndex/segmentIndex",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:connectome",
-          "name": "paper_l4_full_connectome",
-          "path": "./segmentation/zarr/connectomes/paper_l4_full_connectome",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "multiscale",
-          "name": "prediction",
-          "attributes": {
-            "webknossos:category": "color",
-            "webknossos:bounding_box": {
-              "topleft": { "c": 0, "x": 128, "y": 128, "z": 128 },
-              "size": { "c": 3, "x": 5445, "y": 8380, "z": 3285 }
-            },
-            "webknossos:data_type": "uint8",
-            "webknossos:rendering": { "is_disabled": true }
-          },
-          "path": "./prediction"
-        }
-      ]
-    }
-  }
-}
diff --git a/rfc/8/examples/webknossos/inline-multiscale.json b/rfc/8/examples/webknossos/inline-multiscale.json
deleted file mode 100644
index 204ceba5..00000000
--- a/rfc/8/examples/webknossos/inline-multiscale.json
+++ /dev/null
@@ -1,580 +0,0 @@
-{
-  "zarr_format": 3,
-  "node_type": "group",
-  "attributes": {
-    "ome": {
-      "version": "0.7",
-      "type": "collection",
-      "name": "l4dense_motta_et_al_dev_v2",
-      "attributes": {
-        "webknossos:rendering": {
-          "position": { "x": 2850, "y": 4318, "z": 1770 },
-          "zoom": 1.3,
-          "voxel_size": {
-            "factor": [11.239999771118164, 11.239999771118164, 28],
-            "unit": "nanometer"
-          }
-        }
-      },
-      "nodes": [
-        {
-          "type": "multiscale",
-          "name": "color",
-          "attributes": {
-            "webknossos:category": "color",
-            "webknossos:bounding_box": {
-              "topleft": { "x": 128, "y": 128, "z": 128 },
-              "size": { "x": 5445, "y": 8380, "z": 3285 }
-            },
-            "webknossos:data_type": "uint8"
-          },
-          "multiscales": [
-            {
-              "axes": [
-                { "name": "c", "type": "channel" },
-                { "name": "x", "type": "space", "unit": "nanometer" },
-                { "name": "y", "type": "space", "unit": "nanometer" },
-                { "name": "z", "type": "space", "unit": "nanometer" }
-              ],
-              "datasets": [
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/1",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 11.239999771118164, 11.239999771118164, 28.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/2-2-1",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 22.479999542236328, 22.479999542236328, 28.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/4-4-2",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 44.959999084472656, 44.959999084472656, 56.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/8-8-4",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 89.91999816894531, 89.91999816894531, 112.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/16-16-8",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 179.83999633789062, 179.83999633789062, 224.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/32-32-16",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 359.67999267578125, 359.67999267578125, 448.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/64-64-32",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 719.3599853515625, 719.3599853515625, 896.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/128-128-64",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 1438.719970703125, 1438.719970703125, 1792.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/256-256-128",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 2877.43994140625, 2877.43994140625, 3584.0]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/512-512-256",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 5754.8798828125, 5754.8798828125, 7168.0]
-                    }
-                  ]
-                },
-                {
-                  "path": "/absolute/path/to/l4dense_motta_et_al_demo/color/1024-1024-512",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 11509.759765625, 11509.759765625, 14336.0]
-                    }
-                  ]
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "type": "multiscale",
-          "name": "segmentation",
-          "attributes": {
-            "webknossos:category": "segmentation",
-            "webknossos:bounding_box": {
-              "topleft": { "x": 0, "y": 0, "z": 0 },
-              "size": { "x": 5632, "y": 8704, "z": 3584 }
-            },
-            "webknossos:data_type": "uint32",
-            "webknossos:values": { "max": 100000 }
-          },
-          "multiscales": [
-            {
-              "axes": [
-                { "name": "c", "type": "channel" },
-                { "name": "x", "type": "space", "unit": "nanometer" },
-                { "name": "y", "type": "space", "unit": "nanometer" },
-                { "name": "z", "type": "space", "unit": "nanometer" }
-              ],
-              "datasets": [
-                {
-                  "path": "./segmentation/1",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 11.239999771118164, 11.239999771118164, 28.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/2-2-1",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 22.479999542236328, 22.479999542236328, 28.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/4-4-2",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 44.959999084472656, 44.959999084472656, 56.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/8-8-4",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 89.91999816894531, 89.91999816894531, 112.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/16-16-8",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 179.83999633789062, 179.83999633789062, 224.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/32-32-16",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 359.67999267578125, 359.67999267578125, 448.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/64-64-32",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 719.3599853515625, 719.3599853515625, 896.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/128-128-64",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 1438.719970703125, 1438.719970703125, 1792.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/256-256-128",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 2877.43994140625, 2877.43994140625, 3584.0]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/512-512-256",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 5754.8798828125, 5754.8798828125, 7168.0]
-                    }
-                  ]
-                },
-                {
-                  "path": "./segmentation/1024-1024-512",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 11509.759765625, 11509.759765625, 14336.0]
-                    }
-                  ]
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "type": "webknossos:mesh",
-          "name": "meshfile_4-4-2",
-          "path": "./segmentation/zarr/meshes/meshfile_4-4-2",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_5",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_5",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_10",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_10",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_15",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_15",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_20",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_20",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_25",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_25",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_30",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_30",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_35",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_35",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_40",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_40",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_45",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_45",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_50",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_50",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_55",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_55",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_60",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_60",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_65",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_65",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_70",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_70",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_75",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_75",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_80",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_80",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_85",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_85",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_90",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_90",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_95",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_95",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:agglomeration",
-          "name": "agglomerate_view_100",
-          "path": "./segmentation/zarr/agglomerates/agglomerate_view_100",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:segment_index",
-          "name": "segmentIndex",
-          "path": "./segmentation/zarr/segmentIndex/segmentIndex",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "webknossos:connectome",
-          "name": "paper_l4_full_connectome",
-          "path": "./segmentation/zarr/connectomes/paper_l4_full_connectome",
-          "attributes": { "webknossos:parent": "segmentation" }
-        },
-        {
-          "type": "multiscale",
-          "name": "prediction",
-          "attributes": {
-            "webknossos:category": "color",
-            "webknossos:bounding_box": {
-              "topleft": { "c": 0, "x": 128, "y": 128, "z": 128 },
-              "size": { "c": 3, "x": 5445, "y": 8380, "z": 3285 }
-            },
-            "webknossos:data_type": "uint8",
-            "webknossos:rendering": { "is_disabled": true }
-          },
-          "multiscales": [
-            {
-              "axes": [
-                { "name": "c", "type": "channel" },
-                { "name": "x", "type": "space", "unit": "nanometer" },
-                { "name": "y", "type": "space", "unit": "nanometer" },
-                { "name": "z", "type": "space", "unit": "nanometer" }
-              ],
-              "datasets": [
-                {
-                  "path": "./prediction/1",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 11.239999771118164, 11.239999771118164, 28.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/2-2-1",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 22.479999542236328, 22.479999542236328, 28.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/4-4-2",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 44.959999084472656, 44.959999084472656, 56.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/8-8-4",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 89.91999816894531, 89.91999816894531, 112.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/16-16-8",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 179.83999633789062, 179.83999633789062, 224.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/32-32-16",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 359.67999267578125, 359.67999267578125, 448.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/64-64-32",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 719.3599853515625, 719.3599853515625, 896.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/128-128-64",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [
-                        1.0, 1438.719970703125, 1438.719970703125, 1792.0
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/256-256-128",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 2877.43994140625, 2877.43994140625, 3584.0]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/512-512-256",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 5754.8798828125, 5754.8798828125, 7168.0]
-                    }
-                  ]
-                },
-                {
-                  "path": "./prediction/1024-1024-512",
-                  "coordinateTransformations": [
-                    {
-                      "type": "scale",
-                      "scale": [1.0, 11509.759765625, 11509.759765625, 14336.0]
-                    }
-                  ]
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    }
-  }
-}

From fa5e319fd0c4cac49c610f394bda6f8272484b98 Mon Sep 17 00:00:00 2001
From: Norman Rzepka 
Date: Fri, 16 Jan 2026 21:28:58 +0100
Subject: [PATCH 16/19] consistency

---
 rfc/8/index.md | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/rfc/8/index.md b/rfc/8/index.md
index bfbb012c..9a9e86cc 100644
--- a/rfc/8/index.md
+++ b/rfc/8/index.md
@@ -231,15 +231,15 @@ Objects that implement `Node` have the following fields:
 | `"attributes"` | object | no | [See attributes section](#attributes) |
 
 The `type` field of a `Node` defines the additional fields, if any, it has. 
-This RFC proposed two Node types: `Collection`, `Multiscale` and `Singlescale`.
+This RFC defines three `Node` types: `Collection`, `Multiscale`, and `Singlescale`.
 Future RFCs might add more Node types, including custom Node types.
 
-A Node object may be used as the root object of the `ome` key, in which case a `version` key, as defined in previous spec versions, is also required.
-Non-root Node objects SHOULD not have `version` field and MUST NOT have a different `version` value than the root Node.
+A `Node` object may be used as the root object of the `ome` key, in which case a `version` field, as defined in previous spec versions, is also required.
+Non-root `Node` objects SHOULD NOT have a `version` field and MUST NOT have a different `version` value than the root `Node`.
 
 #### `Collection` Node
 
-References a Node that is a collection of Nodes. 
+References a `Node` that is a collection of `Node`s. 
 Collections MAY be nested.
 
 | Field | Type | Required? | Notes |
@@ -255,7 +255,7 @@ Either `"nodes"` or `"path"` MUST be present, but not both.
 
 #### `Multiscale` Node
 
-References a Node that represents an OME-Zarr multiscale image.
+References a `Node` that represents an OME-Zarr multiscale image.
 This new interface replaces the multiscale metadata defined in the previous versions of the OME-Zarr specification.
 
 | Field | Type | Required? | Notes |
@@ -272,7 +272,7 @@ Either `"nodes"` or `"path"` MUST be present, but not both.
 
 #### `Singlescale` Node
 
-References a Node that represents one resolution representation of an OME-Zarr multiscale image.
+References a `Node` that represents one resolution representation of an OME-Zarr multiscale image.
 This new interface replaces the multiscale metadata defined in the previous versions of the OME-Zarr specification.
 
 | Field | Type | Required? | Notes |
@@ -283,9 +283,9 @@ This new interface replaces the multiscale metadata defined in the previous vers
 | `"path"` | object | yes | Value must be a `Path` object. |
 | `"attributes"` | string | yes | Value must be a dictionary. [See attributes section](#attributes). |
 
-Singlescale nodes MUST have a `"coordinateTransformations"` key in their attributes which conforms to the [coordinate transformations](#coordinate-transformations) specification and only contains "scale" and "translate" transformations.
+`Singlescale` nodes MUST have a `coordinateTransformations` key in their `attributes` which conforms to the [coordinate transformations](#coordinate-transformations) specification and only contains `scale` and `translate` transformations.
 
-#### Paths
+#### `Path`
 
 This new interface replaces the paths defined in the previous versions of the OME-Zarr specification.
 
@@ -294,7 +294,7 @@ This new interface replaces the paths defined in the previous versions of the OM
 | `"type"` | string | yes | Value must be valid path type. |
 | `"path"` | string | yes | Value must be a string containing a path. See below. |
 
-The path `"type"` defines how the path is interpreted. Currently, the `"zarr"` and `"json"` types are supported. 
+The `type` field defines how the path is interpreted. Currently, the `zarr` and `json` types are supported. 
 The `"zarr"` type is used for paths that reference nodes in a Zarr array or group. Implementations need to append `zarr.json` to the path to access the metadata of the referenced node.
 The `"json"` type is used for paths that reference nodes in a JSON file.
 
@@ -321,7 +321,7 @@ In any case, implementations may impose access restrictions on any type of paths
 
 #### References
 
-Objects that are being referenced MUST have an `"id"` key.
+Objects that are being referenced MUST have an `id` field.
 
 The reference can be a string with an ID for referencing objects within the same JSON document.
 For more complex references, the reference can be an object with the following fields:
@@ -331,13 +331,13 @@ For more complex references, the reference can be an object with the following f
 | `"id"` | string | yes | Value must be a string that matches `[a-zA-Z0-9-_.]+`. |
 | `"path"` | object | no | Value must be a `Path` object. |
 
-For external references, the `"path"` key MUST be present.
+For external references, the `path` field MUST be present.
 
 
 #### Attributes
 
-Nodes have `attributes` keys that can be populated with arbitrary JSON metadata. 
-A primary use case for the attributes is the specialization of collections and nodes through additional metadata.
+Each `Node` has an `attributes` field that can be populated with JSON metadata. 
+A primary use case for the `attributes` field is the specialization of collections and nodes through additional metadata.
 
 There are unprefixed and prefixed top-level keys in the `attributes` dictionary.
 Unprefixed keys are reserved. 
@@ -350,17 +350,17 @@ The `ome:` prefix is reserved.
 
 We envision that popular implementations will claim prefixes to customize their metadata, e.g. `mobie:`, `neuroglancer:`, `fractal:`, `webknossos:`.
 
-Custom-prefixed keys can also be used to add additional sub-keys or behavior to existing attributes.
+Custom-prefixed keys can also be used to add additional sub-keys or behavior to existing keys.
 This can be thought of as a way of achieving inheritance.
-For example, the `well` keys could be specialized by a `fractal:well` key that adds additional sub-keys with altering behavior.
+For example, the `well` key could be specialized by a `fractal:well` key that adds additional sub-keys or altering behavior.
 It is out-of-scope of this RFC to fully define the inheritance behavior.
-That is left for specializing attributes to define on a case-by-case basis and may be standardized in a future RFC.
+That is left to be defined on a case-by-case basis for individual key specifications and may be standardized in a future RFC.
 
 While attributes are effective for creating specialized collections and nodes, implementations are not required to parse them.
 Implementations are encouraged to provide graceful fallback strategies for specialized collections and nodes that are not understood by the implementation. 
 Strategies could include falling back to basic collection semantics, providing selector screens, or rendering nodes with default settings.
 
-Unprefixed attributes that are defined as part of this RFC are:
+Unprefixed keys that are defined as part of this RFC are:
 - `coordinateSystems`
 - `coordinateTransformations`
 - `labels`, as well as `label-value` and `color` in label attributes
@@ -598,7 +598,7 @@ The `colors` field is an array of objects with the following fields:
 
 If present, the `color` field MUST have an array with four integers between 0 and 255, inclusive. These integers represent the uint8 values of red, green, blue and alpha.
 
-Additional attributes MAY be added to the `attributes` field, following the attribute naming rules.
+Additional keys MAY be added, following the key naming rules.
 
 
 #### Example
@@ -804,7 +804,7 @@ The `coordinateTransformations` field is an array of objects with the following
 | `"input"` | string | yes | Value must be a reference to the input coordinate system. |
 | `"output"` | string | yes | Value must be a reference to the input coordinate system. |
 
-Additional attributes MAY be added as required by the transform type.
+Additional fields MAY be added as required by the transform type.
 
 Please note that the semantics of the `input` and `output` fields are changed from by-name to by-reference (ID or reference object) compared to RFC-5
 

From 91f877000743d3aac5c4550bc83eeb3f58f0f561 Mon Sep 17 00:00:00 2001
From: Norman Rzepka 
Date: Fri, 16 Jan 2026 21:34:56 +0100
Subject: [PATCH 17/19] consistency

---
 rfc/8/index.md | 62 +++++++++++++++++++++++++-------------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/rfc/8/index.md b/rfc/8/index.md
index 9a9e86cc..b6403836 100644
--- a/rfc/8/index.md
+++ b/rfc/8/index.md
@@ -226,8 +226,8 @@ Objects that implement `Node` have the following fields:
 | Field | Type | Required? | Notes |
 | - | - | - | - |
 | `"type"` | string | yes | Identifies the type of the node |
-| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
-| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within the enclosing collection. |
+| `"id"` | string | no | Value MUST be a string that matches `[a-zA-Z0-9-_.]+`. IDs MUST be unique within the JSON document. |
+| `"name"` | string | yes | Value MUST be a non-empty string. It SHOULD be a string that matches `[a-zA-Z0-9-_.]+`. Names MUST be unique within the enclosing collection. |
 | `"attributes"` | object | no | [See attributes section](#attributes) |
 
 The `type` field of a `Node` defines the additional fields, if any, it has. 
@@ -244,12 +244,12 @@ Collections MAY be nested.
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
-| `"type"` | string | yes | Value must be `"collection"`. |
-| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
-| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within the enclosing collection. |
-| `"nodes"` | array | no | Value must be an array of `Node` objects. |
-| `"path"` | object | no | Value must be a `Path` object. |
-| `"attributes"` | object | no | Value must be a dictionary. [See attributes section](#attributes). |
+| `"type"` | string | yes | Value MUST be `"collection"`. |
+| `"id"` | string | no | Value MUST be a string that matches `[a-zA-Z0-9-_.]+`. IDs MUST be unique within the JSON document. |
+| `"name"` | string | yes | Value MUST be a non-empty string. It SHOULD be a string that matches `[a-zA-Z0-9-_.]+`. Names MUST be unique within the enclosing collection. |
+| `"nodes"` | array | no | Value MUST be an array of `Node` objects. |
+| `"path"` | object | no | Value MUST be a `Path` object. |
+| `"attributes"` | object | no | Value MUST be a dictionary. [See attributes section](#attributes). |
 
 Either `"nodes"` or `"path"` MUST be present, but not both.
 
@@ -260,12 +260,12 @@ This new interface replaces the multiscale metadata defined in the previous vers
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
-| `"type"` | string | yes | Value must be `"multiscale"`. |
-| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
-| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within one collections JSON file. |
-| `"nodes"` | array | no | Value must be an array of `Singlescale` objects. |
-| `"path"` | object | no | Value must be a `Path` object. |
-| `"attributes"` | string | no | Value must be a dictionary. [See attributes section](#attributes). |
+| `"type"` | string | yes | Value MUST be `"multiscale"`. |
+| `"id"` | string | no | Value MUST be a string that matches `[a-zA-Z0-9-_.]+`. IDs MUST be unique within the JSON document. |
+| `"name"` | string | yes | Value MUST be a non-empty string. It SHOULD be a string that matches `[a-zA-Z0-9-_.]+`. Names MUST be unique within one collections JSON file. |
+| `"nodes"` | array | no | Value MUST be an array of `Singlescale` objects. |
+| `"path"` | object | no | Value MUST be a `Path` object. |
+| `"attributes"` | string | no | Value MUST be a dictionary. [See attributes section](#attributes). |
 
 Either `"nodes"` or `"path"` MUST be present, but not both.
 
@@ -277,11 +277,11 @@ This new interface replaces the multiscale metadata defined in the previous vers
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
-| `"type"` | string | yes | Value must be `"multiscale"`. |
-| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
-| `"name"` | string | yes | Value must be a non-empty string. It should be a string that matches `[a-zA-Z0-9-_.]+`. Must be unique within one collections JSON file. |
-| `"path"` | object | yes | Value must be a `Path` object. |
-| `"attributes"` | string | yes | Value must be a dictionary. [See attributes section](#attributes). |
+| `"type"` | string | yes | Value MUST be `"multiscale"`. |
+| `"id"` | string | no | Value MUST be a string that matches `[a-zA-Z0-9-_.]+`. IDs MUST be unique within the JSON document. |
+| `"name"` | string | yes | Value MUST be a non-empty string. It SHOULD be a string that matches `[a-zA-Z0-9-_.]+`. Names MUST be unique within one collections JSON file. |
+| `"path"` | object | yes | Value MUST be a `Path` object. |
+| `"attributes"` | string | yes | Value MUST be a dictionary. [See attributes section](#attributes). |
 
 `Singlescale` nodes MUST have a `coordinateTransformations` key in their `attributes` which conforms to the [coordinate transformations](#coordinate-transformations) specification and only contains `scale` and `translate` transformations.
 
@@ -291,8 +291,8 @@ This new interface replaces the paths defined in the previous versions of the OM
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
-| `"type"` | string | yes | Value must be valid path type. |
-| `"path"` | string | yes | Value must be a string containing a path. See below. |
+| `"type"` | string | yes | Value MUST be valid path type. |
+| `"path"` | string | yes | Value MUST be a string containing a path. See below. |
 
 The `type` field defines how the path is interpreted. Currently, the `zarr` and `json` types are supported. 
 The `"zarr"` type is used for paths that reference nodes in a Zarr array or group. Implementations need to append `zarr.json` to the path to access the metadata of the referenced node.
@@ -328,8 +328,8 @@ For more complex references, the reference can be an object with the following f
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
-| `"id"` | string | yes | Value must be a string that matches `[a-zA-Z0-9-_.]+`. |
-| `"path"` | object | no | Value must be a `Path` object. |
+| `"id"` | string | yes | Value MUST be a string that matches `[a-zA-Z0-9-_.]+`. |
+| `"path"` | object | no | Value MUST be a `Path` object. |
 
 For external references, the `path` field MUST be present.
 
@@ -593,8 +593,8 @@ The `colors` field is an array of objects with the following fields:
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
-| `"label-value"` | number | yes | Value must be the label value. |
-| `"color"` | array of number | no | Value must be a color in array format. | 
+| `"label-value"` | number | yes | Value MUST be the label value. |
+| `"color"` | array of number | no | Value MUST be a color in array format. | 
 
 If present, the `color` field MUST have an array with four integers between 0 and 255, inclusive. These integers represent the uint8 values of red, green, blue and alpha.
 
@@ -789,9 +789,9 @@ The `coordinateSystems` attribute is an array of objects with the following fiel
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
-| `"id"` | string | no | Value must be a string that matches `[a-zA-Z0-9-_.]+`. IDs must be unique within the JSON document. |
-| `"name"` | string | yes | Value must be a non-empty string. As defined in RFC-5. |
-| `"axes"` | array of strings | yes | Value must be an array of axes, as defined in RFC-5. |
+| `"id"` | string | no | Value MUST be a string that matches `[a-zA-Z0-9-_.]+`. IDs MUST be unique within the JSON document. |
+| `"name"` | string | yes | Value MUST be a non-empty string. As defined in RFC-5. |
+| `"axes"` | array of strings | yes | Value MUST be an array of axes, as defined in RFC-5. |
 
 
 #### Coordinate transforms
@@ -800,9 +800,9 @@ The `coordinateTransformations` field is an array of objects with the following
 
 | Field | Type | Required? | Notes |
 | - | - | - | - |
-| `"type"` | string | yes | Value must be a valid coordinate transform type, as defined in RFC-5. |
-| `"input"` | string | yes | Value must be a reference to the input coordinate system. |
-| `"output"` | string | yes | Value must be a reference to the input coordinate system. |
+| `"type"` | string | yes | Value MUST be a valid coordinate transform type, as defined in RFC-5. |
+| `"input"` | string | yes | Value MUST be a reference to the input coordinate system. |
+| `"output"` | string | yes | Value MUST be a reference to the input coordinate system. |
 
 Additional fields MAY be added as required by the transform type.
 

From f623ee2dd417c19eaa08fec8b27b0440e32fdfed Mon Sep 17 00:00:00 2001
From: Norman Rzepka 
Date: Sat, 17 Jan 2026 20:33:12 +0100
Subject: [PATCH 18/19] text organization

---
 rfc/8/index.md | 78 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 52 insertions(+), 26 deletions(-)

diff --git a/rfc/8/index.md b/rfc/8/index.md
index b6403836..75985201 100644
--- a/rfc/8/index.md
+++ b/rfc/8/index.md
@@ -280,11 +280,15 @@ This new interface replaces the multiscale metadata defined in the previous vers
 | `"type"` | string | yes | Value MUST be `"multiscale"`. |
 | `"id"` | string | no | Value MUST be a string that matches `[a-zA-Z0-9-_.]+`. IDs MUST be unique within the JSON document. |
 | `"name"` | string | yes | Value MUST be a non-empty string. It SHOULD be a string that matches `[a-zA-Z0-9-_.]+`. Names MUST be unique within one collections JSON file. |
-| `"path"` | object | yes | Value MUST be a `Path` object. |
+| `"path"` | object | no | Value MUST be a `Path` object. |
 | `"attributes"` | string | yes | Value MUST be a dictionary. [See attributes section](#attributes). |
 
 `Singlescale` nodes MUST have a `coordinateTransformations` key in their `attributes` which conforms to the [coordinate transformations](#coordinate-transformations) specification and only contains `scale` and `translate` transformations.
 
+If the `Singlescale` node is the root node and contained within the `zarr.json` of a Zarr array, the `path` field SHOULD NOT be present. 
+In this case, the `Singlescale` describes the Zarr array.
+Otherwise, the `path` field MUST be present.
+
 #### `Path`
 
 This new interface replaces the paths defined in the previous versions of the OME-Zarr specification.
@@ -336,31 +340,18 @@ For external references, the `path` field MUST be present.
 
 #### Attributes
 
-Each `Node` has an `attributes` field that can be populated with JSON metadata. 
+Each `Node` has an `attributes` field that can be populated with JSON metadata.
 A primary use case for the `attributes` field is the specialization of collections and nodes through additional metadata.
 
-There are unprefixed and prefixed top-level keys in the `attributes` dictionary.
-Unprefixed keys are reserved. 
-Changes to or additions of unprefixed keys are expected to be made through the RFC process.
-Custom keys SHOULD be namespaced by a prefix (separated by `:`).
-Prefixes SHOULD be registered in a central registry by individuals or organizations (e.g. dev teams), which will be a Github repository under the `ome` organization.
-Registration of a prefix claim maintainership for that prefix.
-The registry also provides a discoverable location for specification of the keys.
-The `ome:` prefix is reserved.
-
-We envision that popular implementations will claim prefixes to customize their metadata, e.g. `mobie:`, `neuroglancer:`, `fractal:`, `webknossos:`.
+Attribute keys follow the naming scheme described in [Extensibility](#extensibility): unprefixed keys are reserved for the core specification, while prefixed keys (e.g., `mobie:`, `neuroglancer:`, `fractal:`, `webknossos:`) allow custom metadata.
 
-Custom-prefixed keys can also be used to add additional sub-keys or behavior to existing keys.
+Custom-prefixed keys can also be used to add additional sub-keys or behavior to existing unprefixed keys.
 This can be thought of as a way of achieving inheritance.
-For example, the `well` key could be specialized by a `fractal:well` key that adds additional sub-keys or altering behavior.
+For example, the `well` key could be specialized by a `fractal:well` key that adds additional sub-keys or alters behavior.
 It is out-of-scope of this RFC to fully define the inheritance behavior.
 That is left to be defined on a case-by-case basis for individual key specifications and may be standardized in a future RFC.
 
-While attributes are effective for creating specialized collections and nodes, implementations are not required to parse them.
-Implementations are encouraged to provide graceful fallback strategies for specialized collections and nodes that are not understood by the implementation. 
-Strategies could include falling back to basic collection semantics, providing selector screens, or rendering nodes with default settings.
-
-Unprefixed keys that are defined as part of this RFC are:
+Unprefixed attribute keys that are defined as part of this RFC are:
 - `coordinateSystems`
 - `coordinateTransformations`
 - `labels`, as well as `label-value` and `color` in label attributes
@@ -369,16 +360,51 @@ Unprefixed keys that are defined as part of this RFC are:
 ### Extensibility
 
 Adding collections to OME-Zarr provides an opportunity to define extension points.
+Extension points allow the specification to be extended in a controlled manner, enabling custom functionality while maintaining interoperability.
+
+#### Naming scheme
+
+Extension identifiers follow a prefixed vs unprefixed convention:
+
+- **Unprefixed identifiers** are reserved for the core specification and can only be added or modified through the RFC process.
+- **Prefixed identifiers** (separated by `:`) can be freely introduced by custom extensions without requiring an RFC. The prefix identifies the user or organization that introduces and maintains the extension. Prefixes SHOULD be registered in a central registry (a Github repository under the `ome` organization). Registration of a prefix claims maintainership for that prefix and provides a discoverable location for the specification of custom extensions.
+- The `ome:` prefix is reserved for official extensions that have not yet been incorporated into the core specification.
+
+This naming scheme applies uniformly to all extension points listed below.
+
+Implementations SHOULD ignore extension identifiers they do not recognize, allowing graceful degradation when encountering unknown extensions.
+
+#### Extension points
+
+The following extension points are defined:
+
+##### Node types
+
+The `type` field of a `Node` defines its structure and semantics. This RFC defines three unprefixed node types: `collection`, `multiscale`, and `singlescale`. Custom extensions can add prefixed node types (e.g., `mobie:table`, `fractal:roi`).
+
+Implementations that do not recognize a node type SHOULD treat it as an opaque node and MAY skip it or display it with a generic representation.
+
+##### Attribute keys
+
+Attribute keys within the `attributes` dictionary of nodes are an extension point. Custom extensions can add prefixed keys (e.g., `neuroglancer:shader`, `webknossos:settings`). See [Attributes](#attributes) for more details.
+
+##### Path types
+
+The `type` field of a `Path` object defines how the path is interpreted. This RFC defines two unprefixed path types: `zarr` and `json`. Custom extensions can add prefixed path types for other storage protocols or access patterns (e.g., `myorg:s3`, `myorg:zip`).
+
+Implementations that do not recognize a path type SHOULD treat the referenced node as opaque and MAY skip it or display it with a generic representation.
+
+##### Coordinate transformation types
+
+The `type` field of a coordinate transformation defines its mathematical operation. RFC-5 defines several unprefixed transformation types including `identity`, `scale`, `translation`, and others. Custom extensions can add prefixed transformation types (e.g., `myorg:nonlinear`).
+
+Implementations that do not recognize a transformation type SHOULD report an error or skip the transformation, as applying an unknown transformation could lead to incorrect spatial interpretation.
 
-TODO: Explain naming scheme, similar to attributes (prefixed vs unprefixed)
+##### Coordinate system axis types
 
-TODO: List and explain Extension points
+The `type` field of an axis in a coordinate system defines its semantics. RFC-5 defines unprefixed axis types including `space`, `time`, and `channel`. Custom extensions can add prefixed axis types (e.g., `myorg:wavelength`).
 
-- Node types
-- Attributes
-- Path types
-- Coordinate transforms
-- Coordinate system axes
+Implementations that do not recognize an axis type MAY treat it as an opaque dimension.
 
 
 ### Examples

From 3f653f9e525004aa3db494bc8f5b862b8778e2d3 Mon Sep 17 00:00:00 2001
From: Norman Rzepka 
Date: Mon, 26 Jan 2026 11:48:01 +0100
Subject: [PATCH 19/19] cleanup

---
 rfc/8/index.md | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/rfc/8/index.md b/rfc/8/index.md
index 75985201..36466106 100644
--- a/rfc/8/index.md
+++ b/rfc/8/index.md
@@ -25,15 +25,6 @@ This proposal is early. Status: D1
 | Reviewer  | N/A           | N/A         | xxxx-xx-xx | Endorse (link to comment)             |
 | Reviewer  | N/A           | N/A         | xxxx-xx-xx | Requested by editor                   |-->
 
-### TODO
-- Path objects
-- Rework the multiscale node; including inlining multiscales
-- Attribute merging
-- Topology, can a collection reference itself
-- Names unique per collection instead of file and define references ("../" or UUID)
-- Extension points (extract from attributes section)
-
-
 ## Overview
 
 This proposal adds a new "collection" concept to OME-Zarr.