Choosing between Git and Corotation

Git lets you choose which changes become commits, maintain branches, and integrate them when ready. Sharing usually means committing and pushing; receiving changes means fetching and merging or pulling. Its merge machinery can combine compatible text edits and leaves conflicting ones for you or your tools to resolve. See Git’s guides to recording changes, remotes, and branching and merging.

Corotation is for a continuously shared project: cor work batches saves, submits whole packages to current, and receives teammates’ updates automatically. Periodic baselines provide recovery points, but there is no authored commit history or branch workflow. Competing packages are accepted or rejected as a whole; Corotation preserves rejected work for a person or active agent to repair. It does not merge file contents itself.

Git can also be automated and self-hosted. Agents can use either tool. Corotation supplies conflict monitoring and repair skills for its continuous workflow. Neither tool requires paid hosting or a code review process.

Why chunks instead of whole asset versions

Git LFS represents a large file with a pointer in Git and stores the file itself separately. On GitHub, each changed LFS version uploads and stores the entire file, even for a small edit. See GitHub’s LFS storage documentation.

Corotation identifies smaller, content-defined chunks and reuses them across files, versions, and clients. An update transfers only chunks missing at the destination. This comparison is about Git LFS: Git itself can delta-compress objects in packfiles, as described in Git’s packfile documentation. Re-encoding a compressed asset can change most of its bytes, so a small visual edit does not guarantee a small transfer.

One current node

Current owns the authoritative namespace and serializes package publication. Each client owns its editable workspace, local chunk cache, durable outgoing requests, and incoming recovery journal.

Paths carry the sequence at which they last changed. A deletion is a tombstone with its own sequence, so deleting and recreating a file cannot make an older client’s precondition valid by accident.

Chunk-level deduplication

A file version consists of its size, executable bit, and an ordered list of chunk hashes and lengths. Corotation uses FastCDC v2020 content-defined chunking with:

Chunk size Value
Minimum 64 KiB
Target average 256 KiB
Maximum 1 MiB

BLAKE3 identifies chunks across files, versions, and clients. A client asks which hashes are missing, then transfers only those chunks. New chunks are grouped into immutable packs of roughly 8 MiB to amortize durable file writes.

Insertions usually disturb only nearby boundaries. Re-encoding a compressed asset may change most chunks. Changed files still need to be read locally, and incoming versions are reconstructed as complete destination files.

Whole-package publication

An outgoing package contains a UUID and path changes, each with an expected version. Current checks every expected version and the resulting namespace inside a serialized SQLite transaction.

One failed check rejects the entire package. An accepted package updates all its entries, an ordered event, the global sequence, and a durable receipt together. SQLite uses WAL mode with synchronous=FULL.

Receipts make retries idempotent. Retrying the same package returns its original acceptance or rejection; reusing the ID with different content fails.

The client exchange

  1. Recover any interrupted incoming apply and retry durable pending outgoing work.
  2. Scan relevant local paths. A brand-new client first adopts or records conflicts from a coherent latest snapshot.
  3. For an established client, persist and submit its entire local package before catch-up. This keeps an incoming change from splitting an outgoing batch.
  4. Apply the receipt or block every path in a rejected package.
  5. Consume ordered events, or a baseline after compaction. Persist applied, conflicted, or deferred incoming state before advancing the cursor.

Installation and recovery

Incoming bytes are verified before storage. Before replacing a working file, the client rescans it, persists an apply plan, and preserves displaced bytes in .laplace/recovery/. A no-clobber hard-link install avoids overwriting a destination that unexpectedly appears.

Server acceptance is atomic; a working directory is not

Ordinary filesystems cannot replace multiple files at once. An editor can observe an incoming package partway through installation. The journal and displaced copies support recovery, but a package is not a coherent snapshot of an application that saves related files at different times.

Local measurements

In a recorded release-build run on arm64 macOS, inserting 19 bytes into a seeded 256 MiB random file produced 163,809 bytes of new chunks. The rest reused stored content. Initial end-to-end capture and upload measured 116 MiB/s; download and installation measured 168 MiB/s.

These are single-run observations from September 12, 2026, not hardware-independent promises. The benchmark excludes watcher batching and initial connection setup. Real networks, caches, asset encodings, and concurrent load change the results.

Read the measurement notes · Storage result JSON · Sync result JSON

Protocol details

The source includes the full wire format, HTTP endpoints, pack layout, and durability notes in ARCHITECTURE.md. Protocol version is currently 1; future on-disk and wire formats have no migration guarantee yet.