mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 15:08:24 +00:00
135 lines
6.9 KiB
Markdown
135 lines
6.9 KiB
Markdown
# Announcements Purgatory System
|
|
|
|
**ID:** 3ca0
|
|
|
|
## Problem
|
|
|
|
Currently, acceptable announcements that don't replace existing announcements are immediately accepted and served to clients. We need a "purgatory" system where new announcements are held in a pending state until they become relevant (when a corresponding state event arrives).
|
|
|
|
This prevents serving announcements for repositories that may never receive state events, while still maintaining the git infrastructure in case they do.
|
|
|
|
## Requirements
|
|
|
|
### 1. Purgatory Instead of Immediate Acceptance
|
|
- Acceptable announcements that do not replace an existing announcement should go to purgatory instead of being immediately accepted and served
|
|
- The bare git repo should still be created when an announcement enters purgatory
|
|
- Announcements should not be served to clients while in purgatory
|
|
|
|
### 2. Expiry and Cleanup
|
|
- If an announcement expires while in purgatory, the bare git repo should be deleted
|
|
- Need to track expiry times for announcements in purgatory
|
|
- Background cleanup mechanism to handle expired purgatory announcements
|
|
|
|
### 3. State Event Interaction
|
|
- When a state event arrives, any announcements in purgatory should have their expiry extended to match the state event's expiry
|
|
- This keeps purgatory announcements alive as long as they might become relevant
|
|
- Need to determine when/how announcements transition from purgatory to active
|
|
|
|
### 4. State Event Acceptability
|
|
- State event acceptability checks must consider announcements in purgatory
|
|
- A state event should be rejected if it would conflict with announcements in purgatory (not just active announcements)
|
|
- Validation logic needs to check both active and purgatory announcements
|
|
|
|
## Plan
|
|
|
|
- [x] Phase 1: Design
|
|
- Design doc: `docs/explanation/announcements-purgatory-design.md`
|
|
- Implementation doc: `docs/explanation/announcements-purgatory-implementation.md`
|
|
|
|
- [x] Phase 2: Core implementation (commit 1d09e4b)
|
|
- AnnouncementPurgatoryEntry type and DashMap store
|
|
- Route new announcements to purgatory (replacements skip)
|
|
- Promote on git data arrival (process_purgatory_announcements)
|
|
- Authorization checks purgatory (fetch_repository_data_with_purgatory)
|
|
- State policy uses purgatory for maintainer validation
|
|
- Cleanup task handles announcement expiry
|
|
- Updated count()/cleanup() to 3-tuples
|
|
|
|
- [ ] Phase 3: Implement SyncLevel and fix sync integration (ROOT CAUSE of test failure)
|
|
- The sync module doesn't fetch state events for purgatory announcements
|
|
because they're not saved to DB and thus never "confirmed" as repos
|
|
- The fix per design doc (decision #6) is SyncLevel, NOT treating
|
|
purgatory as fully confirmed. Full confirmation would over-fetch
|
|
L2/L3 events (PRs, issues) that get rejected anyway.
|
|
- Add SyncLevel enum (StateOnly vs Full) to RepoSyncNeeds
|
|
- When announcement enters purgatory, register in sync index with
|
|
SyncLevel::StateOnly (only fetches kind 30618 state events)
|
|
- On promotion, upgrade sync level to Full
|
|
- Modify filter building in src/sync/filters.rs to partition repos
|
|
by sync level and build appropriate filters
|
|
- Revert the partial fix in commit 1d09e4b that treats
|
|
ProcessResult::Purgatory as confirmed in pending_sync_index
|
|
(wrong approach - would trigger full L2/L3 sync)
|
|
- Keep the hot cache invalidation for rejected state events (correct)
|
|
- This should fix test_archive_read_only_creates_bare_repo
|
|
|
|
- [ ] Phase 4: Announcement persistence (save/restore)
|
|
- save_to_disk() and restore_from_disk() skip announcement_purgatory
|
|
- PurgatoryState struct has no announcement field
|
|
- Need SerializableAnnouncementPurgatoryEntry type
|
|
- Need save/restore logic with Instant offset conversion
|
|
- Need persistence tests (purgatory_persistence.rs currently asserts 0)
|
|
|
|
- [ ] Phase 5: Remaining design features
|
|
- Soft expiry two-phase - delete bare repo but retain event for 24h,
|
|
allow revival on state event arrival
|
|
- Expiry extension - extend_announcement_expiry() exists but is never
|
|
called from state policy or git auth
|
|
- Newer announcement replaces older in purgatory (not just DB check)
|
|
- Service change clears purgatory entry
|
|
- Deletion event (kind 5) removes from purgatory
|
|
|
|
- [ ] Phase 6: Testing
|
|
- Fix test_archive_read_only_creates_bare_repo
|
|
- Add persistence round-trip tests for announcements
|
|
- Test new functionality from Phase 5 as implemented
|
|
|
|
## Progress
|
|
|
|
### 2026-01-23 [Session 00:00]
|
|
- Started: Created issue with requirements and initial plan
|
|
- Created worktree: worktrees/3ca0-announcements-purgatory
|
|
- Ready to begin implementation
|
|
|
|
### 2026-01-23 [Design Session]
|
|
- Conducted extensive architectural review with multiple iterations
|
|
- Clarified requirements based on user feedback:
|
|
- Problem: Prevent serving empty bare repos indefinitely (misleads clients)
|
|
- Trigger: Git data arrival promotes announcements (not state events)
|
|
- Indexing: Must use (pubkey, identifier) tuple (identifier not unique)
|
|
- Expiry extension: Two places (state event arrival AND git auth)
|
|
- Edge cases: Newer announcements replace older, service list changes
|
|
- Created design document: `docs/explanation/announcements-purgatory-design.md`
|
|
- OpenCode conversation: https://opencode.ai/c/01JJBXPFVVQVX5RVQF2KQBQZJR
|
|
|
|
### 2026-02-05 [Design Completion]
|
|
- Completed high-level design with user review
|
|
- Key decisions finalized:
|
|
- **Sync integration**: Purgatory announcements sync state events only (SyncLevel::StateOnly)
|
|
- **Authorization**: Must check purgatory announcements in addition to DB
|
|
- **Soft expiry**: Delete bare repo but retain event for 24h (allows revival on state event)
|
|
- Created implementation details document: `docs/explanation/announcements-purgatory-implementation.md`
|
|
- Design documents committed: 603c87f
|
|
|
|
### 2026-02-13 [Core Implementation]
|
|
- Implemented core announcement purgatory (commit 1d09e4b)
|
|
- Happy path works: announcement -> purgatory -> git push -> promotion -> served
|
|
- All purgatory integration tests pass (44/44)
|
|
- One existing test broken: test_archive_read_only_creates_bare_repo
|
|
- Root cause identified: sync module does not treat purgatory announcements
|
|
as "confirmed repos", so per-repo sync never fetches state events for them.
|
|
The sync flow is: fetch announcements via negentropy -> save to DB marks them
|
|
"confirmed" -> for each confirmed repo, fetch state/PR events. Purgatory
|
|
announcements skip the DB save, so they're never confirmed.
|
|
- Partial fix applied: ProcessResult::Purgatory now counts as confirmed in
|
|
pending_sync_index, and announcements entering purgatory invalidate
|
|
previously-rejected state events from the hot cache
|
|
- Also identified: announcement persistence not implemented (save_to_disk
|
|
and restore_from_disk skip announcement_purgatory entirely)
|
|
|
|
## Notes
|
|
|
|
- This feature prevents resource waste on announcements that never receive git data
|
|
- Maintains quick response time for repositories that do become active
|
|
- Soft expiry solves the failed_events problem without permanent blocklisting
|