Skip to content

Revisions: your archive's timeline

Think of a bound laboratory logbook. Every time something changes, you write one dated entry, and each entry points back to the page before it. You never tear a page out, and a spoiled entry is never written at all: if an experiment fails, there is nothing to cross out. Read the book up to any page and you know exactly what the lab looked like that day. MTRL keeps the same kind of book for your archive, and each entry in it is a revision (one committed change to the archive).

Every successful top-level change to the science in your archive commits exactly one revision. Adding a run, adding a checkpoint, transforming, correcting, replacing, removing a run, and ingesting an instrument file each write one entry. Nothing writes half an entry, and nothing writes two.

A revision captures the archive’s state at that moment:

  • its own identity, a RevisionId;
  • its parent, the immediately prior revision — the history is one straight line, never a tangle of branches;
  • the active selections: which exact record each logical name, such as the “spectrum” checkpoint, pointed at when the entry was written;
  • the ordered events of that change, and the time it was committed.

Every revision in one history shares a single ArchiveId, the identity of the whole book. Once written, an entry is frozen: after commit, and after load, neither the revision nor its events can be edited.

Plenty of operations leave the logbook untouched, because they only read what is already committed. Saving the archive, verifying it, and exporting a receipt create no revision. Neither does configuring the operation registry. An aggregate call on its own writes nothing either: it prepares a candidate result, and the entry appears only when you add that result to the archive.

A failed change also writes no entry. MTRL validates the whole change before committing, so a failure rolls back completely: no new record, no change to lineage, and no new revision. The revision count after a failure is the revision count before it. In logbook terms, the spoiled page does not exist.

Saving writes the complete timeline into the .mtrl file, and loading restores it exactly. A loaded archive does not start a new book: it adopts the saved ArchiveId, restores every saved revision without inventing a synthetic one, and carries on the chain. Your next change becomes a child of the loaded head, as if the archive had never been closed.

Because each revision holds the active selections of its moment, the timeline answers the question “what did the archive look like then?”. Assertion queries can report their state as of an earlier revision, so you can check what the archive claimed before a correction, not only what it claims now.

You have been writing this timeline since the first lesson. Recording the raw “spectrum” checkpoint for ftir-replicate-01 was one entry. The normalised spectrum was another. The correction of the saturated peak in Fix a mistake was one more — and every earlier entry stayed exactly as written. The exact attributes of a revision are listed in the reference.

To see how revisions sit inside the file alongside records, manifests, and integrity data, read Inside a .mtrl archive. For the difference between the ArchiveId that names this whole timeline and the RevisionId that names one entry in it, revisit Two kinds of identity.