Field guide/Foundations
Foundations

Content-addressed source control: objects, trees, and moving refs

How immutable content IDs support reuse, why canonical encoding matters, and why hashing alone does not provide durability or authorization.

Content addressing identifies an object from its contents rather than its location. If two clients request the same immutable object ID, a cache can reuse the corresponding bytes. That is a useful building block, but it is only one part of a source control system.

Git already stores content-addressed objects. File contents become blobs, trees connect names to objects, and commits connect a tree to history and metadata. Content addressing is therefore not a property that distinguishes all new designs from Git. The useful comparison concerns the representation, protocol, and operations built around those objects. Git object model

Read the OpenScion object boundary

At the reviewed OpenScion revision, object IDs are BLAKE3 hashes of a header and payload. The header incorporates object kind and payload length, so a blob and a tree with identical payload bytes receive different IDs. Object hashing implementation

The conceptual operation is:

object ID = hash(kind + encoded length + payload)

The actual separators and byte encoding matter; the expression above is an explanation, not a wire-format specification. A client must follow the implementation’s exact format to produce matching IDs.

Canonical encoding makes logically equivalent inputs serialize consistently. OpenScion’s tree encoder expects sorted, unique names. Its changeset encoder writes parents, ordered file changes, author, message, time, and metadata in a specified byte layout. Changing any included field can change the ID. Tree encoding, changeset encoding

Separate immutable objects from mutable names

A branch-like ref answers a different question: which changeset does this name currently designate? OpenScion updates refs with compare-and-swap. The caller supplies the expected old target and a new target; a stale expectation returns a conflict instead of silently replacing another writer’s update. Ref update implementation

Consider two agents starting from the same target. Both can prepare different changes. Once one moves main, the other must handle the conflict. Compare-and-swap detects the stale publication attempt; it does not merge the files or decide which result is correct. Server-side rebase and landing remain roadmap work in the reviewed version.

What hashing does not solve

An object hash can help verify that received bytes match an expected ID. It does not prove who authored them, who may read them, or whether they survive a crash. Deduplication also needs a retention policy: removing an object still referenced by a revision breaks retrieval.

For service design, test object verification, interrupted uploads, duplicate requests, ref conflicts, and restore integrity separately. Include authorization before returning cache hits. A cache that knows an object exists still needs to decide whether a particular caller may obtain it.

OpenScion’s current store is in memory. Its content-addressed design should not be mistaken for persistent storage. Current object store

Sources