One Lock, Three Writers
The recorder, restore and lifecycle copies all touch the same history repository. That sounds harmless until two of them run at once.
A restore reads objects from a snapshot and writes them back into the worktree. A snapshot stages the worktree and
commits it. If the snapshot stages a file while the restore is halfway through writing it, the commit contains neither
the old content nor the new one. The same race exists in the other direction: a lifecycle copy writes .env, and a
snapshot can stage it before the path is excluded. The file would be in the history before anyone noticed.
Every operation that touches the store takes the per-project repository lock. The lock is shared by all worktrees of a project because they share the object store. The lock is not a global mutex, so different projects still record in parallel; it is the smallest lock that makes the object store safe.
Restore Is Not Checkout
Restore is deliberately conservative. It reads the tree with ls-tree -r -l -z, reads the blobs in one
cat-file --batch, checks every destination against the worktree root, writes through a temporary file and a rename,
restores executable modes and symlinks, skips submodules, and never deletes a file that is absent from the snapshot.
That last rule matters more than it looks. A checkout would make the worktree match the snapshot; that is exactly what a restore from history must not do. The file I created five minutes after the snapshot is not part of the old tree, and removing it would turn recovery into a second accident. A restore in Tachograph is additive: it brings the selected paths back, leaves everything else alone, and lets the next snapshot record the result.
The atomic write is the second half of the same promise. A half-written file is worse than a failed restore, so the content goes to a temporary file, gets its mode, and is renamed into place. If the process dies, the old file remains.
The Lock Is the Feature
The lock is invisible when it works. It becomes visible in the two failure modes it prevents: a snapshot that captures a half-copied secret, and a restore that gets committed midway through. Both are quiet, both are hard to reproduce, and both make the history untrustworthy.
The cost is that a long restore blocks snapshots for that project. That is the right trade. A recorder that records faster than it can recover is not a history; it is a write-only log.
Once two writers could no longer corrupt the store, the remaining question was whether anyone could read it.
The lock and the additive restore answer the same question: what happens when two true things touch the same file? The answer is not to pick a winner quickly, but to make sure the record never contains a state that never existed.
