diff options
| author | Your Name <you@example.com> | 2026-05-26 16:11:05 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-26 16:11:05 +0530 |
| commit | 8816a192c95cf539b65975469a2d61aed46f0414 (patch) | |
| tree | 7590318244a56fabbfa6919ef6d0fab5be529134 /PLAN.md | |
feat: initial implementation of grasp-mirror daemon
GRASP mirror daemon that discovers repos from watched npubs and mirrors
git data + Nostr events across all known GRASP servers for redundancy.
Features:
- Configurable npub watch list via .env (MIRROR_NPUBS)
- TOML config for GRASP server list, index relays, storage paths
- NIP-11 verification of GRASP servers on startup
- Discovery of repos via kind:30617 announcements on index relays
- Git mirroring (bare clone + push --mirror) to missing GRASP servers
- Nostr event forwarding to all GRASP server embedded relays
- SQLite state tracking for sync status and event dedup
- Optional signing key for updating announcements with new clone URLs
- CLI subcommands: daemon, status, verify, mirror-once
Architecture:
config.rs - TOML + .env config loading
db.rs - SQLite state tracking
health.rs - NIP-11 GRASP server verification
discovery.rs - Relay subscription, kind:30617 parsing
git_mirror.rs - Bare clone + push to GRASP servers
nostr_mirror.rs - Event forwarding to all GRASP relays
signing.rs - Optional announcement updates
main.rs - CLI entry point, daemon loop
Diffstat (limited to 'PLAN.md')
| -rw-r--r-- | PLAN.md | 94 |
1 files changed, 94 insertions, 0 deletions
| @@ -0,0 +1,94 @@ | |||
| 1 | # GRASP Mirror Daemon — Implementation Plan | ||
| 2 | |||
| 3 | A Rust daemon that discovers repos from watched npubs and mirrors git data + Nostr events across all known GRASP servers for redundancy. | ||
| 4 | |||
| 5 | ## Phase 1: Core (MVP) | ||
| 6 | |||
| 7 | ### Infrastructure | ||
| 8 | |||
| 9 | - [x] Cargo.toml with dependencies | ||
| 10 | - [x] Project directory structure | ||
| 11 | - [x] PLAN.md (this file) | ||
| 12 | - [ ] config.example.toml | ||
| 13 | - [ ] .env.example | ||
| 14 | - [ ] SQLite migration schema | ||
| 15 | |||
| 16 | ### Source Modules | ||
| 17 | |||
| 18 | - [ ] `config.rs` — TOML config + .env loading, npub parsing, server list | ||
| 19 | - [ ] `db.rs` — SQLite state tracking (repos, sync status, event dedup) | ||
| 20 | - [ ] `health.rs` — NIP-11 GRASP server verification and health checks | ||
| 21 | - [ ] `discovery.rs` — Relay subscriptions for kind:30617/10317/30618, repo parsing | ||
| 22 | - [ ] `git_mirror.rs` — Bare clone + `git push --mirror` to missing GRASP servers | ||
| 23 | - [ ] `nostr_mirror.rs` — Forward Nostr events to all GRASP server relays | ||
| 24 | - [ ] `signing.rs` — Optional: update announcements to include mirrored servers | ||
| 25 | - [ ] `main.rs` — CLI entry point, daemon loop, signal handling | ||
| 26 | |||
| 27 | ## Phase 2: Resilience | ||
| 28 | |||
| 29 | - [ ] Continuous state sync (watch kind:30618, push new refs to missing servers) | ||
| 30 | - [ ] Periodic NIP-11 health checks on all known GRASP servers | ||
| 31 | - [ ] Auto-discover new GRASP servers from indexer kind:10317 events | ||
| 32 | - [ ] Retry with exponential backoff for failed mirrors | ||
| 33 | - [ ] SIGHUP hot-reload of npub list from .env | ||
| 34 | |||
| 35 | ## Phase 3: Advanced | ||
| 36 | |||
| 37 | - [ ] Per-npub / per-repo server allowlists and blocklists | ||
| 38 | - [ ] Prometheus metrics endpoint | ||
| 39 | - [ ] CLI status subcommand (show mirror health per repo/server) | ||
| 40 | - [ ] Web dashboard | ||
| 41 | |||
| 42 | ## Known GRASP Servers | ||
| 43 | |||
| 44 | | Server | Software | GRASP Support | | ||
| 45 | |--------|----------|---------------| | ||
| 46 | | `relay.ngit.dev` | ngit-grasp 1.1.0 | 01/02/06 | | ||
| 47 | | `gitnostr.com` | ngit-grasp 1.0.2 | 01/02/06 | | ||
| 48 | | `git.orangesync.tech` | ngit-grasp 0.1.0 | 01/02/05 | | ||
| 49 | | `ngit.danconwaydev.com` | ngit-grasp 1.0.2 | 01/02/06 | | ||
| 50 | | `git.shakespeare.diy` | ngit-grasp 1.0.1 | 01/02 | | ||
| 51 | | `git.upleb.uk` | ngit-grasp 1.0.2 | 01/02 | | ||
| 52 | | `grasp.budabit.club` | ngit-grasp 1.0.2 | 01/02 | | ||
| 53 | | `git.uid.ovh` | ngit-grasp 1.0.2 | 01/02 | | ||
| 54 | | `git.vps.satsnode.xyz` | ngit-grasp 1.0.1 | 01/02 | | ||
| 55 | |||
| 56 | ## Architecture | ||
| 57 | |||
| 58 | ``` | ||
| 59 | ┌─────────────────────────────────────────────────────┐ | ||
| 60 | │ grasp-mirror │ | ||
| 61 | │ │ | ||
| 62 | │ ┌────────────────┐ ┌─────────────────────────┐ │ | ||
| 63 | │ │ Discovery │ │ Mirror Engine │ │ | ||
| 64 | │ │ ──────────── │ │ ──────────────────── │ │ | ||
| 65 | │ │ • Index relay │────▶│ For each repo: │ │ | ||
| 66 | │ │ • GRASP relays│ │ 1. git clone --bare │ │ | ||
| 67 | │ │ • kind:30617 │ │ from any source │ │ | ||
| 68 | │ │ • kind:10317 │ │ 2. git push --mirror │ │ | ||
| 69 | │ │ • kind:30618 │ │ to missing servers │ │ | ||
| 70 | │ │ │ │ 3. Republish nostr │ │ | ||
| 71 | │ └────────────────┘ │ events to all relays │ │ | ||
| 72 | │ └─────────────────────────┘ │ | ||
| 73 | │ ┌────────────────┐ ┌─────────────────────────┐ │ | ||
| 74 | │ │ Config │ │ State DB (SQLite) │ │ | ||
| 75 | │ │ ──────────── │ │ ──────────────────── │ │ | ||
| 76 | │ │ config.toml │ │ • repos seen │ │ | ||
| 77 | │ │ .env (npubs) │ │ • last sync per server │ │ | ||
| 78 | │ │ [optional] │ │ • sync status/errors │ │ | ||
| 79 | │ │ nsec for │ │ • event ids processed │ │ | ||
| 80 | │ │ signing │ └─────────────────────────┘ │ | ||
| 81 | │ └────────────────┘ │ | ||
| 82 | └─────────────────────────────────────────────────────┘ | ||
| 83 | ``` | ||
| 84 | |||
| 85 | ## Data Flow | ||
| 86 | |||
| 87 | 1. **Discovery**: Subscribe to index relay for kind:30617 from watched npubs | ||
| 88 | 2. **Parse**: Extract repo identifier, clone URLs, relay URLs from each announcement | ||
| 89 | 3. **Diff**: Compare clone URLs against known GRASP servers to find missing mirrors | ||
| 90 | 4. **Mirror Git**: | ||
| 91 | - `git clone --bare` from any available clone URL | ||
| 92 | - For each missing GRASP server: publish announcement to its relay (triggers repo creation), then `git push --mirror` | ||
| 93 | 5. **Mirror Nostr**: Forward all related events (issues, comments, state) to all GRASP server relays | ||
| 94 | 6. **Track**: Record mirror status in SQLite, skip already-mirrored repos on restart | ||