File size: 3,587 Bytes
0720480
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Playbook β€” source code

## What "backed up" means here

Every commit on every branch is reachable from **at least 2 git
remotes**, **at least 1 of them off your laptop**. GitHub's `origin`
counts as one. Acceptable second copies (any one):

- A second remote (Codeberg, GitLab, a self-hosted Forgejo, etc.)
- A clone on a separate machine you control (server, second laptop)
- A documented acceptance in `_project/DECISIONS.md` that GitHub-only
  is enough β€” valid, but record it explicitly so you've made the call

Working state that isn't committed and pushed isn't backed up at all.

## Verification steps

1. **Remotes exist and point somewhere.**

   ```bash
   git remote -v
   ```

   - At least one named `origin`. If none, that's a hard gap.
   - The URL should look like a remote you control (github.com,
     codeberg.org, your own host).

2. **Working tree is clean** (anything dirty isn't backed up).

   ```bash
   git status --short
   ```

   - Empty output β†’ clean.
   - Untracked or modified files β†’ soft gap. Note them; the user may
     have intentionally-uncommitted scratch work, but flag for review.

3. **Every local commit is on a remote.**

   ```bash
   git fetch --all --quiet
   git log --branches --not --remotes --oneline | head
   ```

   - Empty output β†’ all committed work is on at least origin.
   - Any output β†’ those commits exist only locally. Hard gap.

4. **Every local branch has a remote tracking branch.**

   ```bash
   git for-each-ref --format='%(refname:short) %(upstream:short)' refs/heads/ | awk '$2==""'
   ```

   - Empty output β†’ fine.
   - Any output β†’ those branches exist locally without remote
     counterparts. Soft gap.

5. **A second redundancy exists** (the off-host requirement).

   Inspect `git remote -v` for additional remotes beyond `origin`.
   - 2+ remotes β†’ ok.
   - 1 remote (origin only) β†’ check `_project/DECISIONS.md` for an
     entry like "GitHub-only acceptable" or similar. If present, ok. If
     absent, gap: "no second remote and no documented acceptance."

6. **The deployed commit is reachable** (recovery story).

   If `.monitor.yml` lists a primary URL and the project deploys from a
   git ref:
   - Check `_project/RUNBOOK.md` for the deploy procedure.
   - Confirm the deploy uses a remote ref (e.g. `git pull origin main`),
     not a path that requires the developer's laptop. If it depends on
     local state (rsyncing from `~/code/...`), gap.

## What counts as a gap

| Severity | Condition | Example finding line |
|---|---|---|
| Hard | No origin remote | `[backup] source-code: no git remote configured β€” set up GitHub origin` |
| Hard | Local commits not on any remote | `[backup] source-code: <N> local commits not pushed to any remote` |
| Hard | Origin only, no documented acceptance | `[backup] source-code: only one remote (origin); add a second or document the acceptance in DECISIONS.md` |
| Soft | Untracked / modified files | `[backup] source-code: working tree dirty (<file count> files) β€” commit or stash` |
| Soft | Local-only branches | `[backup] source-code: <N> branches without upstream β€” push or delete` |
| Soft | Deploy depends on local state | `[backup] source-code: RUNBOOK references local path for deploy β€” switch to remote-pull` |

Record gaps in `_project/TODO.md` per the format in `verify.md`.

## What to put in BACKUP.md

- All hard gaps closed and at least one soft gap remaining β†’ **gaps**
- All gaps closed β†’ **ok**
- Couldn't run the checks (e.g. not a git repo somehow) β†’ **unverified**

Set "last verified" to today.