upleb.uk

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

summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-01-12 22:37:49 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-01-12 22:37:49 +0000
commitab3337d0a3bf25c282f4d48e5d6150cf291f41e5 (patch)
tree25175a55d9fc90e804fcea93455b437ec9e2f791 /docs
parentc8ab2c9c294ae9401ff542d0eecc6606b7908412 (diff)
docs: updates to deletion design based on blacklists
Diffstat (limited to 'docs')
-rw-r--r--docs/explanation/deletion-requests.md193
1 files changed, 189 insertions, 4 deletions
diff --git a/docs/explanation/deletion-requests.md b/docs/explanation/deletion-requests.md
index 5d6284b..7660774 100644
--- a/docs/explanation/deletion-requests.md
+++ b/docs/explanation/deletion-requests.md
@@ -68,10 +68,28 @@ The deletion system uses three separate data stores:
682. **Holding Database:** Recovery mechanism, prevents accidental permanent deletion 682. **Holding Database:** Recovery mechanism, prevents accidental permanent deletion
693. **Archive Filesystem:** Git data backup, compressed storage 693. **Archive Filesystem:** Git data backup, compressed storage
70 70
71### Holding Database Operations
72
73**Automatic Operations:**
74- **Move to holding:** NIP-09 deletions, blacklist deletions
75- **Automatic recovery:** Re-publishing after NIP-09 deletion (within retention window)
76- **Expiry cleanup:** Daily background task removes entries older than retention period
77
78**Manual Operations:**
79- **Manual ejection:** Operator force-deletes before retention expires
80 - Use case: Large repos consuming excessive storage
81 - Use case: Confirmed malware requiring immediate permanent deletion
82 - Mechanism: CLI command or admin tool (design in Phase 6)
83 - Logged for audit trail
84- **Manual restoration:** Operator restores blacklisted repo after removal from blacklist
85 - Future: May support automatic restoration
86
71## Deletion Flow 87## Deletion Flow
72 88
73### Standard Mode (Respects Deletions) 89### Standard Mode (Respects Deletions)
74 90
91#### NIP-09 Deletion Requests
92
75``` 93```
761. Kind 5 deletion request arrives 941. Kind 5 deletion request arrives
77 95
@@ -95,6 +113,34 @@ The deletion system uses three separate data stores:
95 - Delete corresponding archive files 113 - Delete corresponding archive files
96``` 114```
97 115
116#### Blacklist-Triggered Deletion
117
118When a repository is added to `NGIT_REPOSITORY_BLACKLIST`, the same deletion flow applies:
119
120```
1211. Startup: Scan main DB for repos matching blacklist
122
1232. For each matching repository:
124 - Query dependent events (same cascade logic)
125 - Archive git repository to .archive/<npub>/<identifier>-<timestamp>.tar.gz
126 - Mark metadata as "blacklist-triggered" (not NIP-09)
127 - Move events to holding database
128 - Delete from main database
129
1303. Background task (daily):
131 - Check holding database for expired entries
132 - Delete events older than retention period
133 - Delete corresponding archive files
134```
135
136**Key Differences from NIP-09:**
137- No author validation required (operator decision)
138- Triggered on startup, not by event arrival
139- Metadata marks deletion as blacklist-triggered
140- `deletion_request_disrespector` does NOT prevent blacklist deletion (see below)
141
142**Future:** When dynamic blacklist updates are supported, deletion will trigger immediately on config change instead of waiting for restart.
143
98### Archival Mode (Disrespector) 144### Archival Mode (Disrespector)
99 145
100When `deletion_request_disrespector = true`: 146When `deletion_request_disrespector = true`:
@@ -111,12 +157,22 @@ When `deletion_request_disrespector = true`:
111Result: Archival relay preserves all content 157Result: Archival relay preserves all content
112``` 158```
113 159
160**Important:** Disrespector mode ONLY affects NIP-09 user-initiated deletions. It does NOT prevent blacklist-triggered deletions.
161
162**Rationale:**
163- NIP-09 deletions are user agency decisions (left-pad protection needed)
164- Blacklist deletions are operator moderation decisions (spam/malware/abuse)
165- Archival relays still need ability to moderate malicious content
166- Different policy goals: preservation vs. safety
167
114**Implementation Note:** We need to verify that `nostr-relay-builder` doesn't automatically process deletion requests at the relay library level. If it does, we'll need to override or disable this behavior when disrespector mode is enabled. This will be investigated in Phase 6. 168**Implementation Note:** We need to verify that `nostr-relay-builder` doesn't automatically process deletion requests at the relay library level. If it does, we'll need to override or disable this behavior when disrespector mode is enabled. This will be investigated in Phase 6.
115 169
116## Recovery Mechanism 170## Recovery Mechanism
117 171
118The holding database enables **accidental deletion recovery**: 172The holding database enables **accidental deletion recovery**:
119 173
174### Automatic Recovery (NIP-09 Deletions)
175
120``` 176```
121Scenario: Owner deletes repository, then changes their mind 177Scenario: Owner deletes repository, then changes their mind
122 178
@@ -139,9 +195,102 @@ Scenario: Owner deletes repository, then changes their mind
139 - Return: "New repository created" 195 - Return: "New repository created"
140``` 196```
141 197
198### Blacklist Recovery
199
200When a repository is removed from the blacklist:
201
202**Option 1: Manual Restoration (Initial Implementation)**
203- Operator removes from blacklist config
204- Operator manually restores from holding DB if desired
205- Provides explicit control over recovery decisions
206
207**Option 2: Automatic Restoration (Future Enhancement)**
208- On startup, detect repos in holding area no longer blacklisted
209- Automatically restore to main DB if within retention period
210- Requires careful design to prevent unwanted restorations
211
212**Decision:** Start with manual restoration, evaluate automatic restoration in Phase 6.
213
214### Manual Ejection from Holding Area
215
216Operators need ability to **force-delete** items from holding area before retention period expires:
217
218**Use Cases:**
2191. Large repositories consuming excessive storage
2202. Confirmed malware/abuse that shouldn't be recoverable
2213. Legal/compliance requirements for immediate permanent deletion
222
223**Mechanism (TBD in Phase 6):**
224- Admin CLI command: `ngit-grasp eject <npub>/<identifier>`
225- Or database operation with proper tooling
226- Immediately delete from holding DB and archive filesystem
227- Log operation for audit trail
228- Metric: `ngit_manual_ejections_total`
229
230**Safety Considerations:**
231- Manual ejection is permanent (no undo)
232- Should require confirmation for safety
233- Should log npub, identifier, reason, operator
234- Consider retention policy override vs immediate deletion
235
236## Blacklist Deletion Integration
237
238### Overview
239
240Blacklist-triggered deletions use the **same infrastructure** as NIP-09 deletion requests:
241- Same holding database for 90-day retention
242- Same git archive mechanism
243- Same cascade deletion logic
244- Same recovery capabilities (if unblacklisted)
245
246### Key Differences from NIP-09
247
248| Aspect | NIP-09 Deletion | Blacklist Deletion |
249|--------|----------------|-------------------|
250| **Trigger** | Kind 5 event arrives | Startup scan of main DB |
251| **Author validation** | Required (pubkey match) | Not applicable (operator decision) |
252| **Disrespector mode** | Prevents deletion | Does NOT prevent deletion |
253| **Purpose** | User agency | Moderation/safety |
254| **Recovery** | Automatic (re-publish) | Manual (operator decision) |
255| **Metadata** | Links to Kind 5 event | Marks "blacklist-triggered" |
256
257### Why Disrespector Doesn't Prevent Blacklist Deletion
258
259**Design Decision:** The `deletion_request_disrespector` configuration ONLY affects NIP-09 user-initiated deletions. It does NOT prevent blacklist-triggered deletions.
260
261**Rationale:**
2621. **Different Policy Goals:**
263 - NIP-09 = User agency (prevent left-pad)
264 - Blacklist = Operator safety (prevent spam/malware/abuse)
265
2662. **Archival Relays Need Moderation:**
267 - Archive mode preserves valuable deleted content
268 - But still must handle malicious content
269 - Spam, malware, abuse require operator intervention
270
2713. **Separate Concerns:**
272 - Disrespector = "Don't honor user deletion requests"
273 - Blacklist = "Don't accept these specific repos regardless of source"
274
275### Detection and Timing
276
277**Initial Implementation (Startup Scan):**
278```
2791. Relay starts up
2802. Load blacklist configuration
2813. Scan main database for matching repos
2824. For each match: archive → holding DB → delete from main
2835. Continue normal operation
284```
285
286**Future Enhancement (Dynamic Updates):**
287- Watch for configuration file changes
288- Trigger deletion immediately on blacklist addition
289- Requires careful design to avoid race conditions
290
142## Cascade Deletion Strategy 291## Cascade Deletion Strategy
143 292
144When a repository announcement is deleted, we cascade delete **all dependent events**: 293When a repository announcement is deleted (NIP-09 or blacklist), we cascade delete **all dependent events**:
145 294
146### Rationale 295### Rationale
147 296
@@ -244,7 +393,9 @@ When npub1alice deletes her announcement:
244**Env:** `NGIT_DELETION_REQUEST_DISRESPECTOR` 393**Env:** `NGIT_DELETION_REQUEST_DISRESPECTOR`
245 394
246**Description:** 395**Description:**
247When `true`, relay ignores deletion requests and acts as an archival server. Critical for preventing left-pad scenarios by ensuring at least some relays preserve deleted content. 396When `true`, relay ignores **NIP-09 deletion requests** and acts as an archival server. Critical for preventing left-pad scenarios by ensuring at least some relays preserve deleted content.
397
398**IMPORTANT:** This setting does NOT prevent blacklist-triggered deletions. Blacklist is for operator moderation (spam/malware/abuse), which archival relays still need.
248 399
249**Use Cases:** 400**Use Cases:**
250- Community archival relays 401- Community archival relays
@@ -335,6 +486,10 @@ When implementation is complete, the following documentation will be updated:
335- Large-scale testing 486- Large-scale testing
336- Race condition investigation 487- Race condition investigation
337- Lock strategy finalization 488- Lock strategy finalization
489- **Blacklist deletion behavior** (startup scanning, cascade logic, metadata)
490- **Blacklist + disrespector interaction** (disrespector doesn't prevent blacklist deletion)
491- **Manual ejection mechanism** (CLI command, safety, logging)
492- **Blacklist recovery flow** (manual vs automatic restoration)
338 493
339## Security Considerations 494## Security Considerations
340 495
@@ -357,23 +512,32 @@ When implementation is complete, the following documentation will be updated:
357- Mitigation: Background cleanup enforces retention limits 512- Mitigation: Background cleanup enforces retention limits
358- Mitigation: Compressed tar.gz archives 513- Mitigation: Compressed tar.gz archives
359- Mitigation: Configurable retention period 514- Mitigation: Configurable retention period
515- Mitigation: Manual ejection mechanism for emergency storage relief
360 516
361**Recovery Abuse:** 517**Recovery Abuse:**
362- Mitigation: Recovery only within retention window 518- Mitigation: Recovery only within retention window
363- Mitigation: Must be original owner (pubkey match) 519- Mitigation: Must be original owner (pubkey match)
364- Mitigation: Normal announcement validation applies 520- Mitigation: Normal announcement validation applies
365 521
522**Blacklist Bypass:**
523- Mitigation: Blacklist checked on startup (retroactive deletion)
524- Mitigation: Blacklist checked during announcement validation (prevents new)
525- Mitigation: Blacklist deletion not affected by disrespector mode
526- Note: Manual ejection available for confirmed abuse
527
366## Monitoring & Metrics 528## Monitoring & Metrics
367 529
368**Prometheus Metrics (Planned):** 530**Prometheus Metrics (Planned):**
369- `ngit_deletion_requests_total` - Count of deletion requests received 531- `ngit_deletion_requests_total` - Count of NIP-09 deletion requests received
370- `ngit_deletion_requests_processed` - Count actually processed (disrespector mode = 0) 532- `ngit_deletion_requests_processed` - Count actually processed (disrespector mode = 0)
533- `ngit_blacklist_deletions_total` - Count of blacklist-triggered deletions
371- `ngit_holding_database_events` - Current event count in holding DB 534- `ngit_holding_database_events` - Current event count in holding DB
372- `ngit_holding_database_size_bytes` - Holding DB disk usage 535- `ngit_holding_database_size_bytes` - Holding DB disk usage
373- `ngit_archive_files_total` - Count of archive tar.gz files 536- `ngit_archive_files_total` - Count of archive tar.gz files
374- `ngit_archive_size_bytes` - Total archive disk usage 537- `ngit_archive_size_bytes` - Total archive disk usage
375- `ngit_recoveries_total` - Count of successful recoveries 538- `ngit_recoveries_total` - Count of successful automatic recoveries
376- `ngit_permanent_deletions_total` - Count of events permanently deleted (post-retention) 539- `ngit_permanent_deletions_total` - Count of events permanently deleted (post-retention)
540- `ngit_manual_ejections_total` - Count of operator-initiated ejections from holding area
377 541
378## Testing Strategy 542## Testing Strategy
379 543
@@ -421,6 +585,27 @@ Coordinate between archival relays to ensure redundant preservation of deleted c
421### Recovery Notifications 585### Recovery Notifications
422Notify repository owner when content is recovered from holding database, allowing them to confirm or re-delete. 586Notify repository owner when content is recovered from holding database, allowing them to confirm or re-delete.
423 587
588### Dynamic Blacklist Updates
589Currently blacklist changes only take effect on startup. Future enhancement:
590- Monitor configuration file for changes
591- Apply blacklist additions immediately (trigger deletion)
592- Apply blacklist removals immediately (optional auto-recovery)
593- Requires careful concurrency design
594
595### Automatic Blacklist Recovery
596Currently removing from blacklist requires manual restoration. Future enhancement:
597- Detect unblacklisted repos in holding area on startup
598- Automatically restore if within retention period
599- Configurable policy: auto-restore vs manual-only
600
601### Enhanced Manual Ejection
602Current design includes basic manual ejection. Future enhancements:
603- Web UI for holding area management
604- Batch ejection operations
605- Selective ejection (events only, keep git archive)
606- Export before ejection (backup)
607- Enhanced audit logging with operator identity
608
424## Conclusion 609## Conclusion
425 610
426The deletion request system balances three competing needs: 611The deletion request system balances three competing needs: