One real industrial CT slice as three stacked layers: the scan, then the model's proposal, dashed, then the published label in white, each arriving as its own commit.

Freeze the labels each training job reads.

Nitsor keeps the history of every label and class list, and freezes a dataset version for training while your team keeps correcting the next one.

Real industrial CT, Gruber et al., Fraunhofer EZRT, Me 163 V5 slice 300: the scan, then SAM 2.1's proposal from one box (dashed), run by Nitsor outside the product, then the published label for instance 138 (white), each as its own layer. CC BY 4.0 (opens in a new tab), modified: windowed, cropped, layered and outlined by Nitsor. Sources

  1. M. OseiannotatorAdd bracket, slices 184 to 201dd1eedb9no parent
  2. M. OseiannotatorAdd fastener, slices 190 to 193b1abff39parent dd1eedb9
  3. R. DiazreviewerReview: accept both labels1a3bf591parent b1abff39
  4. K. SantosannotatorAdd ring frame, slices 0 to 511f699d56cparent 1a3bf591
  5. dataset versiondsv_0f3a9c21 pins the last commitmanifest c8f0acfd

Static sample with four computed SHA-256 IDs. JavaScript and Web Crypto enable editing.

Synthetic sample

A commit history. Your browser computes its SHA-256 fingerprints.

Keep the revisions behind each label.

Which labels trained last month's model? Each saved revision records its author and the revision before it, and History counts what it added, removed and changed.

The Changes and Author columns of a Nitsor project's History table: one commit with +4 -0 ~3 changes saved by M. Chen and one with +3 -0 ~0 saved by A. Rivera.

Real chest CT: Armato et al., "Data From LIDC-IDRI", TCIA, CC BY 3.0 (opens in a new tab), modified: cropped. Labels from the LIDC readers' published annotations.

  1. commit 1 · proposal

    The wall of a bottle on a real industrial CT slice, with a model's dashed proposal.

    SAM 2.1, our run

  2. commit 2 · accepted label

    The same wall with the published label in white.

    published instance 138

Two revisions of one slice, shown together here; the viewer opens one at a time. Left: SAM 2.1's proposal, run by Nitsor outside the product. Right: the published label for instance 138. Real industrial CT, Gruber et al., Fraunhofer EZRT, CC BY 4.0 (opens in a new tab), modified: windowed, cropped and outlined by Nitsor. Sources

Open an earlier revision.

Open a saved revision in the viewer to read the labels as they stood, on the same slice and view.

Measured on one label

Commits
proposal to accepted label
Label
instance 138
Kept
4,787 px
Removed
1,130 px
Added
0 px

Measured by Nitsor, outside the product, on slice 300 (512 × 512 pixels): the proposal and the published label overlap at 0.81 IoU.

  1. v1 · 2 classes

    A chest CT slice with the lungs outlined as two classes, left and right.
  2. v2 · 5 classes

    The same slice with the lungs outlined as five lobes.

Dashed: TotalSegmentator v2.18's lobe masks, from one run by Nitsor outside the product (right). The left panel is derived from them by merging the lobes of each side; it is not a second model output. Real chest CT, Armato et al., "Data From LIDC-IDRI", TCIA, case LIDC-IDRI-0003, CC BY 3.0 (opens in a new tab), modified: windowed and outlined by Nitsor. Sources

Keep old labels tied to their definitions.

Split one class into several without losing the earlier class list. Each revision keeps the definitions its labels used.

A class list edit

Commit
2c817a0d
Before
lung left, lung right
After
five lung lobes
On merge
a typed conflict instead of an overwrite
Older labels
read under the list they were drawn with
pin.httpHTTP API
# {id} is the Version below.
# The hash is shortened here;
# send all 64 hex characters.
POST /api/v1/dataset-versions/{id}/pin
Authorization: Bearer <token>
Content-Type: application/json

{"manifestHash": "sha256:9f1ce04b…"}

Keep training data fixed as labels change.

A dataset version fixes the scans, labels and class list for a training job. Read it by ID while labelling continues.

A Dataset Version

Version
dsv_0f3a9c21
Commit
2c817a0d
Manifest
9f1ce04b
Pinned by
training-box-7

Pinned members and their digests, fixed for every job that reads it.

  1. v1 · load a

    The damage labels of load step a, in white on black, projected through the specimen.

    93,146 damage voxels: 0° 28,845, ±45° 45,449, 90° 18,852

  2. v2 · load b

    The damage labels of load step b, in white on black, projected through the specimen.

    2,012,257 damage voxels: 0° 628,822, ±45° 989,869, 90° 393,566

  3. v3 · load c

    The damage labels of load step c, in white on black, projected through the specimen.

    2,712,265 damage voxels: 0° 998,567, ±45° 1,270,331, 90° 443,367

  4. v4 · load d

    The damage labels of load step d, in white on black, projected through the specimen.

    3,942,059 damage voxels: 0° 1,634,833, ±45° 1,663,700, 90° 643,526

  5. v5 · load e

    The damage labels of load step e, in white on black, projected through the specimen.

    5,671,727 damage voxels: 0° 2,103,281, ±45° 2,169,416, 90° 1,399,030

Damage voxels under each panel, by ply class:

  • 0° plies
  • ±45° plies
  • 90° plies

One composite specimen scanned at five load steps, each with the damage its trained annotators labelled in three ply classes, shown through the whole thickness (a projection, derived by Nitsor) and cropped to the damaged region. Each load step is its own scan. Kopp, Joseph, Ni, Roy and Wardle, MIT, CC0 (opens in a new tab), modified: projected, cropped and drawn in white by Nitsor. Sources

Labels that grow, version by version.

Scan the specimen again under more load, and its new labels go into a new dataset version. Earlier versions stay as they were, so a model trained on v2 traces back to exactly what v2 held.

Five versions of one specimen

v1 · load a
93,146 damage voxels
v3 · load c
2,712,265
v5 · load e
5,671,727
Classes
0°, ±45° and 90° plies, kept apart

Voxel counts from the published labels of each load step. Load a has little damage: 93,146 voxels, faint at this size.

Show us what you inspect.

Start with a public CT or MRI scan. See how a model suggestion becomes a reviewed label and a fixed training dataset.