From a12927181c571fc1641772ad44dd4c6a4ab209d9 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Mon, 12 Jan 2026 20:30:13 +0000 Subject: feat(grasp-05): add read-only mode with auto-enable for archive configs Implements NGIT_ARCHIVE_READ_ONLY configuration option that defaults to true when archive mode is enabled, allowing relays to operate as read-only syncs of archived repositories. Key changes: - Add NGIT_ARCHIVE_READ_ONLY config option (defaults to true if archive enabled) - NIP-11 advertises GRASP-05 support and includes curation field when read-only - Validation logic rejects non-whitelisted repos in read-only mode - Comprehensive tests for read-only behavior and defaults - Full documentation in config reference, .env.example, and NixOS module Read-only mode enables passive mirroring without being listed in announcements, useful for backup/archive operations while preventing accidental write acceptance. --- docs/explanation/grasp-05-archive.md | 25 ++++++++++--- docs/reference/configuration.md | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 5 deletions(-) (limited to 'docs') diff --git a/docs/explanation/grasp-05-archive.md b/docs/explanation/grasp-05-archive.md index e43a87e..45481dd 100644 --- a/docs/explanation/grasp-05-archive.md +++ b/docs/explanation/grasp-05-archive.md @@ -35,14 +35,17 @@ Archive mode relaxes the "must list service" requirement for whitelisted reposit **Configuration:** ```bash -# Specific repos (safest) +# Specific repos (safest) - read-only by default NGIT_ARCHIVE_WHITELIST=npub1torvalds.../linux,npub1satoshi.../bitcoin +# NGIT_ARCHIVE_READ_ONLY defaults to true # All repos from trusted maintainers NGIT_ARCHIVE_WHITELIST=npub1alice...,npub1bob... +# NGIT_ARCHIVE_READ_ONLY defaults to true # Archive everything (⚠️ storage risk) NGIT_ARCHIVE_ALL=true +# NGIT_ARCHIVE_READ_ONLY defaults to true ``` ### Validation Priority @@ -63,11 +66,21 @@ Archived repos use the same directory structure as hosted repos: / npub1alice.../ hosted-repo.git/ # Lists your service (writable) - archived-repo.git/ # Whitelisted (read-only) + archived-repo.git/ # Whitelisted (read-only by default) ``` **No flags or metadata** - archive status determined dynamically from config + announcement contents. +### Read-Only Mode + +By default, archive mode operates in read-only mode (`NGIT_ARCHIVE_READ_ONLY=true`): +- Repository announcements are accepted per whitelist/archive-all configuration +- The service is **not listed** in accepted announcements (passive sync only) +- NIP-11 document advertises `GRASP-05` support +- NIP-11 `curation` field indicates read-only sync scope: + - `"Read-only sync of all repositories found on network"` (if `NGIT_ARCHIVE_ALL=true`) + - `"Read-only sync of whitelisted repositories and maintainers"` (if whitelist configured) + ### Full Sync Archived repositories trigger complete GRASP-02 sync: @@ -129,12 +142,14 @@ Watch for: ## Comparison: Hosted vs Archived -| Aspect | Hosted (GRASP-01) | Archived (GRASP-05) | -|--------|-------------------|---------------------| +| Aspect | Hosted (GRASP-01) | Archived (GRASP-05 Read-Only) | +|--------|-------------------|-------------------------------| | Announcement must list you | ✅ Required | ❌ Whitelisted instead | | Git pushes | ✅ Accepted | ❌ Rejected (read-only) | | GRASP-02 sync | ✅ Full sync | ✅ Full sync | -| Relay discovery | ✅ Listed | ❌ Not listed | +| Relay discovery | ✅ Listed in announcements | ❌ Not listed (passive sync) | +| NIP-11 supported_grasps | `["GRASP-01", "GRASP-02"]` | `["GRASP-01", "GRASP-05", "GRASP-02"]` | +| NIP-11 curation field | `null` | Describes archive scope | | Use case | Hosting workspace | Backup/mirror | ## Related Documentation diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 52418ad..4692600 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -574,6 +574,77 @@ NGIT_ARCHIVE_WHITELIST=npub1alice23...,npub1bob23.../linux,bitcoin-core --- +#### `NGIT_ARCHIVE_READ_ONLY` + +**Description:** Configure relay as read-only sync of archived repositories +**Type:** Boolean +**Default:** `true` if `NGIT_ARCHIVE_ALL` or `NGIT_ARCHIVE_WHITELIST` is set, `false` otherwise +**Required:** No + +**Examples:** + +```bash +# Explicitly enable (requires archive mode) +NGIT_ARCHIVE_READ_ONLY=true + +# Explicitly disable (writable archive repos) +NGIT_ARCHIVE_READ_ONLY=false + +# Automatic (default behavior) +# - If NGIT_ARCHIVE_ALL or NGIT_ARCHIVE_WHITELIST is set → true +# - Otherwise → false +# NGIT_ARCHIVE_READ_ONLY= +``` + +**Behavior:** + +- When `true`: + - NIP-11 document includes `GRASP-05` in `supported_grasps` + - NIP-11 `curation` field describes the archive scope + - Repository announcements not listing this service are accepted per whitelist/archive-all +- When `false`: + - Archive mode disabled (standard GRASP-01 operation) +- When unset (default): + - Automatically `true` if archive mode configured + - Automatically `false` otherwise + +**Error Conditions:** + +```bash +# ERROR: Cannot set read-only without archive config +NGIT_ARCHIVE_READ_ONLY=true +NGIT_ARCHIVE_ALL=false +NGIT_ARCHIVE_WHITELIST= +# → Server fails to start: "NGIT_ARCHIVE_READ_ONLY=true requires either +# NGIT_ARCHIVE_ALL=true or NGIT_ARCHIVE_WHITELIST to be set" +``` + +**NIP-11 Impact:** + +When `NGIT_ARCHIVE_READ_ONLY=true`: +- `supported_grasps`: includes `"GRASP-05"` +- `curation`: Set to one of: + - `"Read-only sync of all repositories found on network"` (if `NGIT_ARCHIVE_ALL=true`) + - `"Read-only sync of whitelisted repositories and maintainers"` (if `NGIT_ARCHIVE_WHITELIST` set) + +**Use Cases:** + +```bash +# Public archive of entire ecosystem +NGIT_ARCHIVE_ALL=true +NGIT_ARCHIVE_READ_ONLY=true # Default + +# Selective backup of critical projects +NGIT_ARCHIVE_WHITELIST=npub1torvalds.../linux,npub1satoshi.../bitcoin +NGIT_ARCHIVE_READ_ONLY=true # Default + +# Writable mirror (advanced, not typical) +NGIT_ARCHIVE_WHITELIST=npub1alice... +NGIT_ARCHIVE_READ_ONLY=false +``` + +--- + ### Logging Configuration #### `RUST_LOG` -- cgit v1.2.3