Two kinds of identity
Think of a book. The title, say The Origin of Species, names the work itself. It stays the same no matter how many printings exist. Each printing, by contrast, is fixed forever: the third printing of 1861 has exactly the pages it has, and no one can change a word of it now. When you cite a fact from the book, you name the printing, not only the title, because only a printing has exact pages. MTRL gives every result the same two kinds of identity, and for the same reason.
The two names every result carries
Section titled “The two names every result carries”Every saved result in MTRL has two identifiers.
- The CheckpointId is the title. It names the logical result: “the spectrum”. It is stable, and it is the name you, your colleagues, and your transforms use when you talk about the result.
- The RecordId is the printing. It names one immutable version of that result. Once a record is committed, its RecordId never changes and its content never changes.
A correction makes the distinction concrete. When you corrected the saturated FTIR spectrum
of polymer-film-01, the CheckpointId stayed: it is still “the spectrum”. MTRL minted a new
RecordId for the corrected version, and the old version kept its own RecordId forever. The
title endured; a new printing was bound.
Pointing at an exact version
Section titled “Pointing at an exact version”Because one CheckpointId can stand behind several records over time, a CheckpointId alone cannot say exactly which data you mean. For that, MTRL uses a RecordRef: a small frozen object that pairs a CheckpointId with a RecordId. It names one exact version of one logical result, with no room for drift.
This is the only acceptable way to point at scientific input. New lineage must never refer
to a CheckpointId alone, because that would leave the version ambiguous. When a transform
records its source, or an aggregate records its members, each reference is a full RecordRef.
A RecordRef also refuses to be built half-hearted: it rejects an empty CheckpointId or
RecordId at construction, so a vague reference cannot exist.
The identity table, in plain words
Section titled “The identity table, in plain words”MTRL uses a handful of identities. Some are logical names for things that persist; the rest are version or history identities for things that are fixed forever.
| Identity | Names | Kind |
|---|---|---|
CheckpointId |
One logical scientific result, such as “the spectrum” | Logical name |
RunId |
One logical instrument or aggregate run, such as ftir-replicate-01 |
Logical name |
RecordId |
One immutable version of a checkpoint | Version identity |
RevisionId |
One committed view of the whole archive | History identity |
ArchiveId |
One archive history, from first commit onwards | History identity |
SampleUid |
One physical specimen or material unit | Physical identity |
Generated identities, such as fresh RecordId, RevisionId, ArchiveId, and SampleUid values, are time-ordered UUIDv7 values. Each one is unique, and newer ones sort after older ones. When you supply your own RunId or CheckpointId, MTRL keeps it; it only asks that logical identifiers are non-empty and safe to use inside archive paths.
Why it matters
Section titled “Why it matters”Two practical guarantees fall out of this split.
Corrections are honest. A correction keeps the CheckpointId and mints a new RecordId, so the logical name your colleagues use survives while the old version remains retrievable by its own RecordId. You saw this in Fix a mistake: the saturated spectrum is still in the history, linked to its corrected successor.
Recipes are exact. Lineage and aggregates point at RecordRefs, not bare checkpoint names, so a recorded recipe always names the exact versions it used. The mean spectrum from your three replicates names each input record precisely. If one replicate is later corrected, the recipe still points at the version it genuinely consumed, and nothing silently retargets.
Where next
Section titled “Where next”Corrections keep the CheckpointId, but a replacement mints a new one — the difference is in Corrections versus replacements. To see both identities at work in code, revisit Fix a mistake.