Modes of Use¶
This page is the diagnostic that decides what the rest of the chapter means for you — whether you are building a Commit Application, a service over the Commit Database, a CLI tool, or a batch script. The architectural choice between single-stream and multi-stream usage — and within multi-stream, between local and strong invariants — is effectively irreversible once a DSM model is sealed: Commit carries no migration tooling, so switching regimes after the fact is a schema rewrite that invalidates existing data.
The asymmetry runs one way: a multi-stream-friendly model is harmless in single-stream usage; a single-stream model has no safe path to multi-stream. In doubt, model for multi-stream.
Two kinds of version DAG¶
Two distinct families of versioning systems share vocabulary (commit, merge, head, parent) and topology (a DAG of nodes with one or more parents), but differ on what a node contains.
Some systems (git, hg, fossil) are snapshot DAGs: each node
contains a full state of the tree. Their merge reconciles
states; when states disagree, the algorithm cannot pick and
surfaces a conflict for human arbitration.
The Commit Database is a mutation DAG: each node contains a
sequence of path-based mutations. Its commitMerge composes
mutation sequences; when mutations target the same path,
deterministic composition rules apply (last-writer-wins by
linearisation order). No conflict is ever surfaced.
This is what makes mechanical reduction possible — and what makes the
Dual-Layer Contract necessary.
Habits built in snapshot DAGs do not transfer cleanly. Read on with this distinction in mind.
Two orthogonal axes¶
How you exercise the mutation DAG splits along two independent axes, and conflating them is the most common source of confusion.
What you can do — the operation axis. Time travel, undo / redo and multi-head exploration are always available, in every context.
Where you do it — the context axis. Single-stream, multi-stream with local invariants, or multi-stream with strong invariants. The context alone decides whether the engine ever has to pick a winner, and therefore whether the Dual-Layer Contract applies to you.
The Dual-Layer Contract applies along the context axis, not the
operation axis. An undo is trivial in single-stream; the same undo
in multi-stream reads through a state an earlier commitMerge
produced. The operation did not change — the context did.
Read both sections as a diagnostic, not a catalogue.
What you can do — the operation axis¶
These three operations are available regardless of context. What
changes with context is not whether you can perform them, but whether
the state they read has already passed through commitMerge.
Time travel¶
Read-only. Reconstruct any past state from a commitId. No writes,
so only the read-side structural guarantees apply: determinism,
immutability, content-addressing.
Undo / redo¶
Append-only. Step back along the chain, diverge, redo. Undo never rewrites history — it masks its target with an Enable/Disable commit. All structural guarantees apply.
Multi-head exploration¶
Parallel heads. Diverge the DAG and keep parallel heads alive, merging them back on your own schedule. Multi-head exploration where a single author reviews each merged result stays single-stream — the merge happens, but one person owns the resulting state.
Important
In single-stream every read returns exactly what you wrote. In
multi-stream every read is an
import
— a state structurally sound but semantically untrusted, to be
re-validated at read time. This includes reads of past states,
because that state was itself produced by commitMerge. The three
operations above do not change between the two contexts; what changes
is the contract around the state they read.
Where you do it — the context axis¶
Single-stream¶
One author writing at a time. No commitMerge is reconstructed at
read time, so the Dual-Layer Contract is
reference material, not load-bearing. Time travel, undo / redo and
multi-head exploration all apply with only the read-side structural
guarantees — there is nothing for the engine to pick between.
Multi-stream¶
Multiple authors’ writes are reduced automatically by mechanical reduction. Two flavours, split by what your invariants look like.
Local invariant — its truth depends only on a structurally disjoint subset of the data (one attachment, one path, one document, or a container used only where it is commutative — a
set/map, or anxarrayread as a set of elements). Two authors writing on disjoint paths cannot break it: the disjointness shields the invariant from reduction.Strong invariant (also called global) — its truth couples data that multiple authors can write in parallel: uniqueness across the whole model (no two assets share an SKU), referential integrity between attachments (an edge must point to an existing vertex), cross-document consistency, or any domain that does not tolerate silent loss (financial, safety, regulatory).
Re-validating at read time closes the gap for local invariants — there was nothing for reduction to break. It does not close the gap for strong invariants: read-side validation can detect a violation, but cannot reconstruct the intent that reduction dropped. The lost information is not recoverable downstream.
Multi-stream with local invariants¶
Multiple authors’ writes are reduced automatically, but the structural drops cost you nothing in practice. Two routes lead here:
Naturally local invariants — the entire mutable state lives in containers whose convergence is commutative by construction (
set/mapunion / subtract), or in anxarrayread only as a set of elements. Anxarrayconverges on membership — no insert is lost — but the relative order of concurrently-inserted elements is not commutative, so an order-dependent invariant is not naturally local. Where the invariant is membership-only, there is nothing for the engine to silently break.Defensive-by-design — cross-attachment references exist and may break under reduction, but the application is built from day one to tolerate the break: load robustly, surface the integrity issue, expose corrective actions to the user. This is an uncommon architectural choice — most applications are not built this way.
The Graph Editor sample exemplifies the second route: EdgeTopology
references vertices, and the model ships ModelIntegrity as a
user-facing repair pool (recreate, delete, or respawn missing
elements), on top of an application that loads graphs with broken
integrity without crashing.
For this mode the Dual-Layer Contract is reference material, not load-bearing.
Multi-stream with strong invariants¶
Multiple authors’ writes are reduced automatically; your invariants are global (uniqueness, referential integrity the engine must uphold), or your domain does not tolerate silent loss (financial, safety, regulatory). This is where the Dual-Layer Contract becomes load-bearing — and where reading it is a diagnostic, not a cookbook: the four post-reduction outcomes (Ignore / Extract a subset / Correct / Reject) collapse to Reject, which is equivalent to saying mechanical reduction was the wrong primitive.
The exit is not better post-reduction handling. It is re-architecting toward multi-stream with local invariants via scope decomposition (see Cooperative Discipline), or building an application-level supervisor on top of Commit — a review UI, a semantic gate, or a coordination protocol that arbitrates before the engine reduces.