The model
Everything in hav is built from six ideas. This page defines them precisely and shows how they fit. Each has a deeper page of its own.
Snap: the fact
A snap (sn-…) is an immutable, content-addressed root tree: the state of
every tracked file, hashed with BLAKE3. A snap is parentless, carrying no
author, no date, no message, and no ancestry inside the hash. Two identical
trees are the same snap, whoever made them, whenever, on whatever history.
Snaps are the record plane. They are never edited, never renumbered, and never carry story.
Knot: the identity
A knot (kn-…) is the stable identity of a unit of work. Its id is random
rather than content-derived, so it survives every change to its content. A
knot's state is a hash-chained sequence of versions, each carrying:
- the snap (what the tree is),
- the description (one line of what this work is),
- the ancestry (parents, or a base, see below).
The working copy is a knot: every command captures the tree into the workspace's knot as a new version. Describing, splitting, and squashing are all history curation, so they append knot versions and touch no content objects.
Untied knots: history is written at land time
A knot created for new work has no parents. It carries a base link instead: the knot-and-snap it grew from (the buoy head at fork or last sync). Ancestry, log, and diff treat the base as a parent edge, so untied work is fully navigable, though its history is not written until it lands.
tie converts the base into the real parent. Because the parent is assigned
at land time, against whatever the buoy head is then, the everyday flow
produces linear history with no rebase ceremony and no merge knots.
The invariant: parents == [] ⟺ base is set. (Sole exception: the init
root, which has neither.)
Buoy: the name
A buoy is a named pointer to a knot: git's branch, minus the checkout state. Buoys only ever reference tied knots. Knots name work (a knot id is the durable way to point at a draft), and buoys name published history. An untied draft's content can change under your feet through capture, cascade, or absorb, which is exactly the illegibility buoys exist to prevent, so every entrance enforces the rule.
You are never "on" a buoy. Workspaces track buoys, and nothing is ever checked out.
Workspace: the place
A workspace (ws-…) is a directory plus a database row
{knot, base buoy, working-copy snap}. Any number of workspaces can track the
same buoy, each holding its own knot, so "already checked out elsewhere" is
inexpressible. The converse is strict: one workspace per knot, ever.
Workspaces are where the files never move under you principle lives. A buoy
advance or a history rewrite never touches a workspace's tree. hav st
notifies, and the always-explicit hav sync is the only verb that moves files
in response to the world changing.
Op: the memory
An op (op-…) is a journal event recording one mutating command, with a
complete before/after view of the repo's mutable state (buoy positions, knot
versions, workspace rows). Ops power undo and redo, including restoring
files on disk, and make every failed multi-step mutation roll back atomically.
Nothing reachable from a retained op is ever deleted.
Conflict: the data
A conflict (cf-…) is an object stored inside a snap: base plus both
sides, structured. Merges, syncs, and rebases always return a snap, possibly
one carrying conflicts, so nothing ever blocks and there is no in-progress
state anywhere. Conflicts materialize as familiar markers only when projected
into a working tree, and editing the file marker-free resolves them.
How it fits together
record plane narrative plane state
┌───────────────────┐ ┌──────────────────────┐ ┌─────────────┐
│ snaps (sn-…) │◄─────│ knots (kn-…) │◄──│ buoys │
│ trees, blobs, │ │ versions: snap + │ │ workspaces │
│ conflicts (cf-…) │ │ description + │ └─────────────┘
│ content-addressed│ │ parents / base │ ▲
└───────────────────┘ └──────────────────────┘ │
▲ ┌─────────────┐
└─────────────────│ op journal │
└─────────────┘- Content is facts (snaps), story lives beside it (knots), names point into the story (buoys), places hold drafts (workspaces), and the journal remembers every move (ops).
- The everyday loop: edit →
describe→tie. Capture is automatic, and naming and landing are the only ceremony. - Secrecy (sealed crews) is a third plane layered over both: key distribution that changes nothing about ids or ancestry.
Deeper reading
- Capture: how the working copy becomes a snap.
- Tie and sync: landing work and following the world.
- Conflicts as data: the merge machinery.
- Rewriting history: edit, squash, split, absorb, and the cascade.
- Workspaces · Undo and the op journal
- Glossary: every term, alphabetized.