Snapshots
A snapshot is a deterministic cryptographic fingerprint of a repository's source code at a specific git commit. It is the foundational building block of CodeQuill -- releases, attestations, and preservations all reference snapshots.
Why Snapshots Exist
Source code is mutable. Files change, commits are amended, branches are rebased, repositories are deleted. When you need to answer "what source code existed at this moment?", the answer often depends on systems that may no longer be available.
A CodeQuill snapshot captures the state of a repository at a precise point in time and produces a Merkle root -- a single cryptographic hash that represents the entire file tree. This Merkle root can be verified independently by anyone with access to the same files.
How Snapshots Work
Step 1: Local Manifest Creation
When you run codequill snapshot, the CLI:
- Reads every tracked file in the repository at the specified commit (defaults to HEAD).
- Computes a
keccak256hash of each file's contents. - Computes a salted hash of each file's path (for privacy -- see below).
- Builds a Merkle tree from the leaf hashes (each leaf =
keccak256(0x00 || path_hash || file_hash)). - Writes the resulting manifest to
.codequill/snapshots/snapshot-<commit>.json.
No source code leaves your machine. The manifest contains only hashes and metadata.
Step 2: Publishing
When you run codequill publish, the CLI:
- Compresses the manifest and uploads it to decentralized storage (IPFS via Lighthouse).
- Submits the Merkle root, commit hash, and manifest CID to the
CodeQuillSnapshotRegistrysmart contract.
The result is a durable, timestamped record: "This Merkle root, representing this file tree, was anchored at this time by this authority."
Privacy Model
File paths in a snapshot are salted before hashing. The salt is derived from the workspace's encryption key, which itself is bound to a registered passkey (WebAuthn). This means snapshot creation requires passkey-based encryption to be set up in the workspace -- the same encryption infrastructure used for preservations and proofs.
Because the salt is passkey-derived:
- The manifest reveals file content hashes but not file paths in plaintext.
- Path verification requires knowledge of the salt (which requires workspace authority and passkey access).
- This allows selective disclosure: you can prove a specific file was included (via Proofs) without revealing the full directory structure.
- Even if a manifest is intercepted, the directory structure remains private without the salt.
Using the CLI
Create a Snapshot
codequill snapshot
This creates a local manifest for the current HEAD commit.
Snapshot Options
| Option | Type | Default | Description |
|---|---|---|---|
--commit <hash> |
string | HEAD | Commit hash to snapshot |
--concurrency <n> |
integer | 8 | Number of concurrent file reads |
--salt <hex> |
string | auto | Custom salt for path hashing (64 hex characters) |
--print-salt |
boolean | false | Display the salt in output (security risk in shared environments) |
Publish a Snapshot
codequill publish
Publishes the snapshot for the current HEAD. You can also specify a commit:
codequill publish a1b2c3d
Publish Options
| Option | Type | Default | Description |
|---|---|---|---|
--no-confirm |
boolean | false | Skip confirmation prompt |
--confirmations <n> |
integer | 1 | Wait for N on-chain confirmations |
--timeout <ms> |
integer | 300000 | Timeout for confirmation (milliseconds) |
--no-wait |
boolean | false | Submit and return immediately |
--json |
boolean | false | Output in JSON format |
View Snapshot History
codequill log
Displays the snapshot history for the current repository, ordered by published time. Optionally limit results:
codequill log --limit 10
Download Published Snapshots
codequill pull
Downloads all published snapshot manifests for the current repository into .codequill/snapshots/. This is useful when working on a new machine or after cloning a repository.
Snapshot Manifests
A snapshot manifest follows the codequill-snapshot:v1 schema. It contains:
- Repository name and commit hash
- Merkle root and content root
- File count
- Per-file entries: path hash, content hash, and file size
- The salt used for path hashing (encrypted)
Manifests are stored as gzip-compressed JSON on IPFS. Anyone can retrieve a manifest using its CID and independently verify the Merkle tree.
What Snapshots Do Not Do
Snapshots record what existed, not how it was used:
- They do not prove how the code was built or compiled.
- They do not guarantee the code is correct, safe, or complete.
- They do not assert anything about the code's origin or authorship (that is what Claims are for).
- They do not prevent the code from being modified after the snapshot is taken.
A snapshot is a receipt. It says: "This exact file tree existed at this moment, as attested by this authority."