# The Backup That Proves Itself, a checked copy every morning and a restore guide on the drive

A sanitised reference implementation. Drop it into Claude Code, point it at what your
business runs on, adapt the list. Generic on purpose, with no business specifics and
no real file names.

## The problem

Most small businesses believe they have a backup until the day they need it. Then
the copy turns out to be months old, or it was never checked, or nobody knows how to
put it back. A backup you have never restored from is a hope, not a backup.

## The idea

Every morning, before the day starts, copy everything the business depends on to an
encrypted drive you own. That means the databases, taken safely while they are in
use, the code with its full history, the settings and the scheduled jobs. Check every
copy after it is made. Fingerprint each file and test that each archive opens. Write
a manifest of what landed, keep a month of daily copies plus one a month for a year,
stay quiet when it works and be loud when it fails. Keep a step by step restore guide
on the drive itself, so getting back does not depend on the computer that just died.

```
07.00 ──> [copy each database safely] ──> [bundle the code with its history, verify]
                                                   │
                                                   v
      [settings and scheduled jobs] ──> [manifest, a fingerprint for every file]
                                                   │
                                                   v
                  [keep 30 dailies and 12 monthlies] ──> quiet if clean, loud if not

      the restore guide sits on the drive, beside the copies
```

## Minimal reference implementation

```python
# backup_that_proves_itself.py, reference only. Swap in your own list of files.
import hashlib
import sqlite3
import subprocess

def snapshot_database(src, dest):
    """A consistent copy of a live database, taken while the app keeps writing.
    Opened read only, so the backup can never change the original."""
    source = sqlite3.connect(f"file:{src}?mode=ro", uri=True)
    target = sqlite3.connect(dest)
    with target:
        source.backup(target)
    source.close()
    target.close()

def fingerprint(path):
    """A SHA-256 per file goes in the manifest, so a later check can prove the
    copy is still the copy."""
    digest = hashlib.sha256()
    with open(path, "rb") as f:
        for chunk in iter(lambda: f.read(1 << 20), b""):
            digest.update(chunk)
    return digest.hexdigest()

def bundle_repo(repo, dest):
    """The whole history in one file, then proved to open."""
    subprocess.run(["git", "-C", repo, "bundle", "create", dest, "--all"], check=True)
    subprocess.run(["git", "-C", repo, "bundle", "verify", dest], check=True)
```

## Why it works

- **Checked, not hoped.** Every copy is proved to open, and every file has a
  fingerprint in the manifest, so the backup tells you it is good rather than
  asking you to believe it.
- **Safe while the business runs.** A database copied with its own backup method is
  consistent even while it is being written to. A plain file copy of a busy database
  can be quietly broken.
- **The way back travels with the copies.** A restore guide on the drive means you
  can recover on a new machine with nothing but the drive and the guide.
- **Quiet when fine, loud when not.** A daily message saying all is well gets ignored
  within a week. Silence plus a loud failure is the only pattern that gets read.
- **The backup is watched too.** A second check looks for the backup's own run each
  morning, so a backup that stops quietly is caught within a day.
- **A drive you own.** Your records stay with you, with no monthly fee.

## Adapt it

- Write down the three things you could not trade without, and back those up first.
- Practise a restore once, on a spare machine, before you ever need it for real. The
  guide gets better every time you follow it.
- Keep the drive encrypted, and keep a second copy somewhere else once the first one
  is running reliably.

Built for my own group of businesses, runs every morning at seven, and this is the
generalised version. Take it, point it at what your business runs on, tell me what
you would add.
