Five ideas that explain everything.
DevSafe is built on a small number of concepts. Once you understand these five, every command and every configuration option will make sense.
Snapshots
A snapshot is a point-in-time capture of a git repository. DevSafe creates snapshots using git bundles, which read directly from the git object database. This is not a filesystem copy. It does not touch your working directory, and it is immune to the file-locking bugs that cause iCloud, Dropbox, and OneDrive to corrupt .git directories.
Each snapshot captures data across five namespaces:
- Index (staged changes)
- Working tree (modified but unstaged files)
- Untracked files (new files not yet added to git)
- Stash (saved work-in-progress)
- Operation state (in-progress merges, rebases, cherry-picks)
This means DevSafe protects work you have not committed yet. If your machine dies mid-rebase, DevSafe can restore exactly where you left off.
$ devsafe status api-server last snapshot: 42 seconds ago namespaces: index, working-tree, untracked, stash bundle size: 18.3 MB (encrypted)
Encryption
Every snapshot is encrypted with AES-256-GCM before it leaves your machine. AES-256-GCM is an authenticated cipher, which means it provides both confidentiality (nobody can read your code) and integrity (nobody can tamper with your backup without detection).
DevSafe uses nonce-unique AEAD. Every encryption operation generates a fresh random nonce. No two encryptions ever reuse the same nonce and key combination.
Keys are organized in a two-level hierarchy using HKDF-SHA256 (a standard key derivation function):
- Master key, generated on your machine and stored in your system keychain
- Per-repo key, derived from the master key + a repo identifier
- Per-bundle key, derived from the repo key + a sequence number
Your master key never leaves your machine. DevSafe never sends key material to any server. The storage provider sees only encrypted blobs.
# Simplified key hierarchy master_key | +- HKDF(master, "repo-a") = repo_key_a | +- HKDF(repo_key_a, "seq:0001") = bundle_key | +- HKDF(repo_key_a, "seq:0002") = bundle_key | +- HKDF(master, "repo-b") = repo_key_b
Because DevSafe never has your key, we cannot recover your data if you lose it. Store your recovery phrase in a password manager or print it on paper. Learn more about key custody.
Chains
Every backup gets a sequence number. That number is baked directly into the storage key (the filename in your user-owned storage):
{repo-id}/{type}/{sequence}.enc # Example keys in your R2 bucket: a1b2c3/committed/000001.enc a1b2c3/committed/000002.enc a1b2c3/working/000001.enc a1b2c3/working/000002.enc
This design enables stateless reconstruction. DevSafe can rebuild your complete backup timeline by listing key names alone. There are no sidecar files, no database, and no manifest to get out of sync. If you can list the contents of your storage bucket, you have your backup inventory.
A single API call (ListObjectsV2) returns everything DevSafe needs to know about your backup history. No downloads required.
Verification
Backups you cannot restore are not backups. DevSafe verifies that every snapshot is restorable without trusting the storage provider.
Verification works in two layers:
- Merkle layer checks structural integrity. Each backup's hash is chained to the previous one, forming a tamper-evident log. If any backup in the chain is modified or deleted, the chain breaks and DevSafe flags it.
- AEAD layer checks cryptographic authenticity. AES-256-GCM includes an authentication tag with every encrypted bundle. On verification, DevSafe decrypts and checks this tag. If a single bit has changed, decryption fails.
DevSafe also supports designated-verifier audits. These let a third party (such as a compliance auditor) confirm that your backups are intact and restorable, without giving them your encryption key.
$ devsafe verify --all verifying 14 repositories (327 snapshots)... ✓ api-server 42 snapshots chain intact ✓ design-tokens 28 snapshots chain intact ✓ marketing-site 31 snapshots chain intact ... 11 more ✓ all chains valid. 0 drift. 0 tamper.
Discovery
DevSafe finds your repositories automatically. Point it at a directory and it walks the filesystem, looking for .git directories. No configuration file, no per-repo setup, no list to maintain.
$ devsafe scan ~/projects ✓ found 14 repositories ~/projects/api-server ~/projects/design-tokens ~/projects/marketing-site ... 11 more
When you create a new repository inside a watched directory, DevSafe picks it up on the next scan. When you delete one, it stops tracking it. You never have to tell DevSafe about individual repos.
Discovery also handles edge cases: it skips repositories that are mid-garbage-collection, detects bare repos and worktree setups, and identifies submodules so each one gets its own backup chain.
Install DevSafe in under five minutes. Follow the Quickstart guide.