upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/PLAN.md
blob: 2664d516196b1896a702f9471841c73b15977f94 (plain)
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
# GRASP Mirror Daemon — Implementation Plan

A Rust daemon that discovers repos from watched npubs and mirrors git data + Nostr events across all known GRASP servers for redundancy.

## Phase 1: Core (MVP)

### Infrastructure

- [x] Cargo.toml with dependencies
- [x] Project directory structure
- [x] PLAN.md (this file)
- [ ] config.example.toml
- [ ] .env.example
- [ ] SQLite migration schema

### Source Modules

- [ ] `config.rs` — TOML config + .env loading, npub parsing, server list
- [ ] `db.rs` — SQLite state tracking (repos, sync status, event dedup)
- [ ] `health.rs` — NIP-11 GRASP server verification and health checks
- [ ] `discovery.rs` — Relay subscriptions for kind:30617/10317/30618, repo parsing
- [ ] `git_mirror.rs` — Bare clone + `git push --mirror` to missing GRASP servers
- [ ] `nostr_mirror.rs` — Forward Nostr events to all GRASP server relays
- [ ] `signing.rs` — Optional: update announcements to include mirrored servers
- [ ] `main.rs` — CLI entry point, daemon loop, signal handling

## Phase 2: Resilience

- [ ] Continuous state sync (watch kind:30618, push new refs to missing servers)
- [ ] Periodic NIP-11 health checks on all known GRASP servers
- [ ] Auto-discover new GRASP servers from indexer kind:10317 events
- [ ] Retry with exponential backoff for failed mirrors
- [ ] SIGHUP hot-reload of npub list from .env

## Phase 3: Advanced

- [ ] Per-npub / per-repo server allowlists and blocklists
- [ ] Prometheus metrics endpoint
- [ ] CLI status subcommand (show mirror health per repo/server)
- [ ] Web dashboard

## Known GRASP Servers

| Server | Software | GRASP Support |
|--------|----------|---------------|
| `relay.ngit.dev` | ngit-grasp 1.1.0 | 01/02/06 |
| `gitnostr.com` | ngit-grasp 1.0.2 | 01/02/06 |
| `git.orangesync.tech` | ngit-grasp 0.1.0 | 01/02/05 |
| `ngit.danconwaydev.com` | ngit-grasp 1.0.2 | 01/02/06 |
| `git.shakespeare.diy` | ngit-grasp 1.0.1 | 01/02 |
| `git.upleb.uk` | ngit-grasp 1.0.2 | 01/02 |
| `grasp.budabit.club` | ngit-grasp 1.0.2 | 01/02 |
| `git.uid.ovh` | ngit-grasp 1.0.2 | 01/02 |
| `git.vps.satsnode.xyz` | ngit-grasp 1.0.1 | 01/02 |

## Architecture

```
┌─────────────────────────────────────────────────────┐
│                   grasp-mirror                       │
│                                                      │
│  ┌────────────────┐     ┌─────────────────────────┐ │
│  │  Discovery     │     │  Mirror Engine           │ │
│  │  ────────────  │     │  ────────────────────    │ │
│  │  • Index relay │────▶│  For each repo:          │ │
│  │  • GRASP relays│     │  1. git clone --bare     │ │
│  │  • kind:30617  │     │     from any source      │ │
│  │  • kind:10317  │     │  2. git push --mirror    │ │
│  │  • kind:30618  │     │     to missing servers   │ │
│  │                │     │  3. Republish nostr      │ │
│  └────────────────┘     │     events to all relays │ │
│                          └─────────────────────────┘ │
│  ┌────────────────┐     ┌─────────────────────────┐ │
│  │  Config         │     │  State DB (SQLite)      │ │
│  │  ────────────  │     │  ────────────────────   │ │
│  │  config.toml   │     │  • repos seen            │ │
│  │  .env (npubs)  │     │  • last sync per server  │ │
│  │  [optional]    │     │  • sync status/errors    │ │
│  │  nsec for      │     │  • event ids processed   │ │
│  │  signing       │     └─────────────────────────┘ │
│  └────────────────┘                                  │
└─────────────────────────────────────────────────────┘
```

## Data Flow

1. **Discovery**: Subscribe to index relay for kind:30617 from watched npubs
2. **Parse**: Extract repo identifier, clone URLs, relay URLs from each announcement
3. **Diff**: Compare clone URLs against known GRASP servers to find missing mirrors
4. **Mirror Git**:
   - `git clone --bare` from any available clone URL
   - For each missing GRASP server: publish announcement to its relay (triggers repo creation), then `git push --mirror`
5. **Mirror Nostr**: Forward all related events (issues, comments, state) to all GRASP server relays
6. **Track**: Record mirror status in SQLite, skip already-mirrored repos on restart