diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-12 17:40:25 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-12 17:40:25 +0000 |
| commit | c29191b1e1239e931c575a926ec9480e594476d6 (patch) | |
| tree | 6fcb776ba34b6fab766ceb613997b07b18e780df /nix | |
| parent | 2b8992631b9dedcfd4ea44e8565b14ac8a5ed8ea (diff) | |
feat(grasp-05): implement archive mode for backup/mirror operation
Implements GRASP-05 specification for accepting repository announcements
that don't list this relay, enabling archive, mirror, and backup use cases.
Core Features:
- Three whitelist formats: <npub>, <npub>/<identifier>, <identifier>
- Archive-all mode for complete ecosystem mirrors
- Fail-fast npub validation at startup
- Read-only enforcement (archived repos reject pushes)
- Full GRASP-02 sync (git data + Nostr events)
- Dynamic archive status (no flags/metadata)
Implementation:
- Add ArchiveWhitelistEntry enum with Pubkey/Repository/Identifier variants
- Add ArchiveConfig with validation and matching logic
- Update AnnouncementResult to include AcceptArchive variant
- Refactor validate_announcement() to return AnnouncementResult with archive check
- Update AnnouncementPolicy with catch-all pattern for cleaner code
- Wire archive config through builder and policy layers
Configuration:
- NGIT_ARCHIVE_ALL: Accept all announcements (⚠️ storage risk)
- NGIT_ARCHIVE_WHITELIST: Comma-separated whitelist entries
- Updated docs, .env.example, and nix/module.nix
Testing:
- 28 unit tests for config parsing and whitelist matching
- 7 integration tests for archive mode validation
- All 296 tests passing
Validation Priority:
1. Lists our service → Accept (GRASP-01, read/write)
2. Is maintainer → AcceptMaintainer (multi-maintainer, read/write)
3. Matches archive config → AcceptArchive (GRASP-05, read-only)
4. None of above → Reject
Security Considerations:
- Archive-all mode has storage/bandwidth DoS risk
- Identifier-only format matches any pubkey (use npub/identifier for high-value)
- Invalid npubs cause startup failure (fail-fast)
Documentation:
- Concise explanation focused on rationale
- Reference docs updated with all config options
- README updated to reflect completed feature
- Removed from roadmap, added to compliance section
See docs/explanation/grasp-05-archive.md for details.
Diffstat (limited to 'nix')
| -rw-r--r-- | nix/module.nix | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/nix/module.nix b/nix/module.nix index 79b0e83..f82f069 100644 --- a/nix/module.nix +++ b/nix/module.nix | |||
| @@ -177,6 +177,25 @@ let | |||
| 177 | description = "Hours before removing relay from naughty list"; | 177 | description = "Hours before removing relay from naughty list"; |
| 178 | }; | 178 | }; |
| 179 | 179 | ||
| 180 | archiveAll = mkOption { | ||
| 181 | type = types.bool; | ||
| 182 | default = false; | ||
| 183 | description = '' | ||
| 184 | Enable GRASP-05 archive mode: accept all repository announcements. | ||
| 185 | WARNING: Storage and bandwidth risk. | ||
| 186 | ''; | ||
| 187 | }; | ||
| 188 | |||
| 189 | archiveWhitelist = mkOption { | ||
| 190 | type = types.listOf types.str; | ||
| 191 | default = [ ]; | ||
| 192 | example = [ "npub1alice..." "npub1bob.../linux" "bitcoin-core" ]; | ||
| 193 | description = '' | ||
| 194 | GRASP-05 archive whitelist entries. | ||
| 195 | Formats: <npub>, <npub>/<identifier>, <identifier> | ||
| 196 | ''; | ||
| 197 | }; | ||
| 198 | |||
| 180 | user = mkOption { | 199 | user = mkOption { |
| 181 | type = types.str; | 200 | type = types.str; |
| 182 | default = "ngit-grasp-${name}"; | 201 | default = "ngit-grasp-${name}"; |
| @@ -217,6 +236,8 @@ let | |||
| 217 | toString cfg.rejectedColdIndexExpirySecs; | 236 | toString cfg.rejectedColdIndexExpirySecs; |
| 218 | NGIT_NAUGHTY_LIST_EXPIRATION_HOURS = | 237 | NGIT_NAUGHTY_LIST_EXPIRATION_HOURS = |
| 219 | toString cfg.naughtyListExpirationHours; | 238 | toString cfg.naughtyListExpirationHours; |
| 239 | NGIT_ARCHIVE_ALL = toString cfg.archiveAll; | ||
| 240 | NGIT_ARCHIVE_WHITELIST = concatStringsSep "," cfg.archiveWhitelist; | ||
| 220 | RUST_LOG = cfg.logLevel; | 241 | RUST_LOG = cfg.logLevel; |
| 221 | } // optionalAttrs (cfg.relayName != null) { | 242 | } // optionalAttrs (cfg.relayName != null) { |
| 222 | NGIT_RELAY_NAME = cfg.relayName; | 243 | NGIT_RELAY_NAME = cfg.relayName; |