diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-23 15:41:32 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-23 15:41:32 +0000 |
| commit | c54ce061d6d278cce8362d5af085808ca60c239b (patch) | |
| tree | ec967d6195d9f7ec4f061449596611afe3a0950f /grasp-audit/src/specs/grasp01/nip11_document.rs | |
| parent | e0ad39a489b3398f8208713bf728db0cb11475b0 (diff) | |
| parent | 113928aa84894ea8f65c247d9987527e792b32a9 (diff) | |
feat: announcement purgatory
Extends purgatory to hold repository announcements until git data arrives,
preventing empty repositories from being served to clients.
When an announcement is received, a bare repo is created immediately and the
announcement is held in purgatory. It is only promoted and served once a git
push confirms real content exists. If no push arrives before expiry, the bare
repo is deleted and the announcement is silently discarded.
Key behaviours:
- Soft expiry: announcements are hidden from clients but kept alive while git
pushes are in progress, reviving on successful push
- Expiry is extended when a matching state event or git push is observed
- NIP-09 deletion events remove announcements from purgatory
- Purgatory state (announcements, state events, PR events, expired set) is
persisted to disk on graceful shutdown and restored on startup, with elapsed
downtime subtracted from expiry deadlines
- Purgatory announcements drive StateOnly sync in the sync system so state
events are fetched from listed relays before promotion
- SyncLevel added to RepoSyncIndex to distinguish purgatory repos (StateOnly)
from promoted repos (Full L2+L3 sync)
Diffstat (limited to 'grasp-audit/src/specs/grasp01/nip11_document.rs')
| -rw-r--r-- | grasp-audit/src/specs/grasp01/nip11_document.rs | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/grasp-audit/src/specs/grasp01/nip11_document.rs b/grasp-audit/src/specs/grasp01/nip11_document.rs index 19ceace..5bf53bd 100644 --- a/grasp-audit/src/specs/grasp01/nip11_document.rs +++ b/grasp-audit/src/specs/grasp01/nip11_document.rs | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | //! - Includes repo_acceptance_criteria field describing acceptance policy | 8 | //! - Includes repo_acceptance_criteria field describing acceptance policy |
| 9 | //! - Handles curation field correctly (present if curated, absent otherwise) | 9 | //! - Handles curation field correctly (present if curated, absent otherwise) |
| 10 | 10 | ||
| 11 | use crate::specs::grasp01::SpecRef; | ||
| 11 | use crate::{AuditClient, AuditResult, TestResult}; | 12 | use crate::{AuditClient, AuditResult, TestResult}; |
| 12 | 13 | ||
| 13 | pub struct Nip11DocumentTests; | 14 | pub struct Nip11DocumentTests; |
| @@ -37,8 +38,8 @@ impl Nip11DocumentTests { | |||
| 37 | pub async fn test_nip11_document_exists(client: &AuditClient) -> TestResult { | 38 | pub async fn test_nip11_document_exists(client: &AuditClient) -> TestResult { |
| 38 | TestResult::new( | 39 | TestResult::new( |
| 39 | "nip11_document_exists", | 40 | "nip11_document_exists", |
| 40 | "GRASP-01:nostr-relay:26", | 41 | SpecRef::Nip11ServeDocument, |
| 41 | "Serve NIP-11 relay information document", | 42 | "MUST serve NIP-11 document", |
| 42 | ) | 43 | ) |
| 43 | .run(|| async { | 44 | .run(|| async { |
| 44 | // 1. Extract HTTP(S) URL from client's WebSocket URL | 45 | // 1. Extract HTTP(S) URL from client's WebSocket URL |
| @@ -96,8 +97,8 @@ impl Nip11DocumentTests { | |||
| 96 | pub async fn test_nip11_supported_grasps_field(client: &AuditClient) -> TestResult { | 97 | pub async fn test_nip11_supported_grasps_field(client: &AuditClient) -> TestResult { |
| 97 | TestResult::new( | 98 | TestResult::new( |
| 98 | "nip11_supported_grasps_field", | 99 | "nip11_supported_grasps_field", |
| 99 | "GRASP-01:nostr-relay:28", | 100 | SpecRef::Nip11ListSupportedGrasps, |
| 100 | "NIP-11 document includes supported_grasps field with GRASP-01", | 101 | "MUST list supported GRASPs as string array", |
| 101 | ) | 102 | ) |
| 102 | .run(|| async { | 103 | .run(|| async { |
| 103 | // 1. Fetch NIP-11 document | 104 | // 1. Fetch NIP-11 document |
| @@ -172,8 +173,8 @@ impl Nip11DocumentTests { | |||
| 172 | pub async fn test_nip11_repo_acceptance_criteria_field(client: &AuditClient) -> TestResult { | 173 | pub async fn test_nip11_repo_acceptance_criteria_field(client: &AuditClient) -> TestResult { |
| 173 | TestResult::new( | 174 | TestResult::new( |
| 174 | "nip11_repo_acceptance_criteria_field", | 175 | "nip11_repo_acceptance_criteria_field", |
| 175 | "GRASP-01:nostr-relay:29", | 176 | SpecRef::Nip11ListRepoAcceptanceCriteria, |
| 176 | "NIP-11 document includes repo_acceptance_criteria field", | 177 | "MUST list repository acceptance criteria", |
| 177 | ) | 178 | ) |
| 178 | .run(|| async { | 179 | .run(|| async { |
| 179 | // 1. Fetch NIP-11 document | 180 | // 1. Fetch NIP-11 document |
| @@ -227,8 +228,8 @@ impl Nip11DocumentTests { | |||
| 227 | pub async fn test_nip11_curation_field(client: &AuditClient) -> TestResult { | 228 | pub async fn test_nip11_curation_field(client: &AuditClient) -> TestResult { |
| 228 | TestResult::new( | 229 | TestResult::new( |
| 229 | "nip11_curation_field", | 230 | "nip11_curation_field", |
| 230 | "GRASP-01:nostr-relay:30", | 231 | SpecRef::Nip11ListCurationPolicy, |
| 231 | "NIP-11 curation field present if curated, absent otherwise", | 232 | "MUST include curation if curated, omit otherwise", |
| 232 | ) | 233 | ) |
| 233 | .run(|| async { | 234 | .run(|| async { |
| 234 | // 1. Fetch NIP-11 document | 235 | // 1. Fetch NIP-11 document |