Skip to main content
All plans Branches, commits, merges, landmarks, positions, Datasets and Dataset Versions are served by the public API under /api/v1/version-graph/ and /api/v1/datasets/, and the dashboard’s Versions tab shows the commits on its Commits and branches page. Review verdicts are recorded through the dashboard editor.

Project

A project contains one version graph and controls access to its history. The graph holds the branches, commits, taxonomy, pipeline, instructions, project assets and Tasks. Who may see or change it is decided by the project rungs described in Roles and provenance. A project is not a storage bucket and not a task queue. Sources are registered at the account level and bound into a project as Project Assets, one Source Version per series role, so several projects can work the same volume without copying it. The queue is a view over Tasks across the projects you can read.

Dataset state

There is no separate “dataset state” record. What a candidate dataset contains is decided by four things, all of which are versioned inside the graph:

Content identity and operational detail

Content identity is the set of facts that decide whether two commits hold the same data. A commit carries a contentRoot, a SHA-256 over the asset, instruction, label, project-metadata, review, taxonomy and workflow roots. Anything that changes that root is a different content state. Anything that does not is operational detail. Two identities are at work here. An annotation’s hash covers its content and provenance and excludes review state, so a verdict never changes the identity of the annotation it judged. A commit’s content root is wider: the review outcomes recorded on the branch are hashed into a review root that is part of it, so recording a verdict does produce a new content root, while leaving every annotation hash where it was. Review and rework explains how verdicts bind content.

Branch

A branch is a line of events inside a project. Every project has a protected main. A branch is created from a known position on another branch (POST /api/v1/version-graph/branches, or through the dashboard when a Task needs one) and holds at most 256 uncommitted events; when 240 have accumulated the control plane writes a safety checkpoint before the next one to keep the event window within its limit. A branch name is descriptive; authority comes from rungs, not from the name.

Commit

A commit names a checkpointed range of events on a branch and carries a commitId, a contentRoot, its parents, an author principal and a structured kind. Nobody presses a commit button. A commit happens when a Task ends with something to record: a Submit with labels or answers, finishing a review, and a Release, Skip or lease expiry that leaves uncommitted events each write one. A Submit with no labels and no answers writes none. The commit and merge APIs retain the caller’s message. A commit is not approval. The review state of each annotation inside it is derived from the verdicts that bind that annotation’s current hash.

Review and decision

A review verdict is an event that carries the hash of the content it judged and is refused if that content has moved. The review rules are described in Review and rework.

Release

Nitsor has no Release object or approval mark on a Dataset Version. A resolved Dataset Version records a selection at a commit, without certifying approval for a use. A Dataset is a named selection over one branch: up to seven clause kinds (assetIds, sourceIds, seriesRoles, labelPrefix, reviewState, provenance, holdout) plus an optional holdout set of asset ids. A Dataset Version pins the branch head at creation and applies that selection at the pinned commit. An asynchronous Request creates the version, identified by five inputs: dataset, commit, selection hash, holdout hash and layout hash. The same five inputs return the existing version marked reused. A resolved version carries a manifest with a SHA-256 digest per 16 MiB chunk, eight members per shard, a stats block reference and a class index. Release a dataset walks the lifecycle.

What each object is and is not

Version model

From a Task to a Dataset Version

Nitsor version-graph sequence as builtA Task on a branch produces events; a Task that ends with something to record writes a commit with a content root; a review verdict binds the hash it judged; a merge into main merges or reports typed conflicts; a Dataset selects over the branch; a Dataset Version freezes the selection at one commit into a digested manifest.Task on a branchannotate, review, auto-label: eventsCommit if a Task has work to recordkind, parents, author, contentRootReview verdict, hash-boundaccept, correct, reject; stale content refusedMerge into mainmerged, or typed conflicts reportedDataset, a selection over the branchclauses, holdout, revisionDataset Version at one commitmanifest hash, per-chunk digests, stats, class indexa Dataset Version records no approval mark

The review verdict is recorded through the dashboard editor; the rest is served by the public API. The Commits and branches page of the Versions tab lists the commits; a Task that ends with nothing to record writes none.

Example state sequence

A typical sequence:
  1. Register a Source from object keys in a connected bucket.
  2. Bind a taxonomy and apply a pipeline to main; each is a checkpoint commit. The API calls applying a pipeline bind, as in POST /api/v1/workflow/definition/bind.
  3. Create Tasks from the Source; annotators claim them from the queue.
  4. A Submit with labels writes an annotate commit; finishing a review writes a review commit.
  5. Define a Dataset over main and create a Dataset Version; the Request resolves to a manifest hash.
  6. Pin the Dataset Version from the training job and read it through the HTTP API. The Python reader is not on PyPI.

Recorded states for work and conflict

Conflict is a recorded state, not an error path. The control plane stores the following states. A Task is one unit of work over one Source at one stage of the pipeline. Those three are the only stored Task states. “Skipped” and “handed back” are events and commit kinds, not states; the project Overview counts skips from the skip records. A merge conflict is one typed disagreement between a source branch and a target branch against their merge base. The conflict types a merge can report are attribute, class, existence, geometry, instructions, provenance, review-state, taxonomy and workflow. Non-overlapping changes merge automatically and are listed as auto-merged entries by kind.

Next step

Read Roles and provenance, then compare this model with the guide to releasing a dataset. The product site describes the same model for a non-technical reader, without the contract detail, at Versioning.
PlansAll plans
Last verified2026-09-30