upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/git/sync.rs
AgeCommit message (Collapse)Author
2026-02-26chore: apply cargo fmt and fix clippy warningsDanConwayDev
Fix pre-existing clippy lints: - &PathBuf -> &Path in audit_cleanup.rs - too_many_arguments on process_newly_available_git_data, process_purgatory_announcements, and HttpService::new - clone_on_copy for PublicKey (Copy type) in purgatory cleanup loop
2026-02-24rename: fetch_repository_data -> ↵DanConwayDev
fetch_repository_data_{excluding,with}_purgatory The old name was ambiguous - it wasn't clear whether purgatory was included or not. The two variants are now explicitly named: - fetch_repository_data_excluding_purgatory: DB only - fetch_repository_data_with_purgatory: DB + purgatory overlay SyncContext trait method also renamed to fetch_repository_data_with_purgatory to match the free function it delegates to.
2026-02-24Fix purgatory announcement not promoted when OIDs arrive via cross-owner ↵DanConwayDev
state event copy When git data is fetched into owner A's repo and a state event for owner B is released from purgatory (copying OIDs from A's repo to B's repo via process_state_with_git_data), owner B's purgatory announcement was never promoted. process_purgatory_announcements only promotes the announcement for the owner derived from source_repo_path (owner A), so owner B's announcement stayed in purgatory with its 30-minute expiry timer running. 30 minutes later the cleanup task would soft-expire owner B's entry, deleting the bare repository even though the announcement had been effectively satisfied. Fix: after a state event is successfully saved to the database, iterate over all announcements in db_repo_data and promote any purgatory announcement for owners whose repos received OIDs via the copy (i.e. repos other than source_repo_path).
2026-02-23Merge master into 3ca0-announcements-purgatoryDanConwayDev
2026-02-23fix: re-process hot-cache maintainer announcements after git push promotionDanConwayDev
When an owner announcement is promoted from purgatory via a git push, any maintainer announcements sitting in the rejected_events_index hot cache were never re-processed. The invalidate_and_get call only existed in SyncManager::process_event_static (the nostr sync path); the git push promotion path (http -> handlers -> git::sync) had no access to the rejected_events_index at all. Thread rejected_events_index and write_policy through the git push path: - process_purgatory_announcements: after saving the promoted announcement, parse its maintainers tag and call invalidate_and_get() for each, then re-process any returned hot-cache events via admit_event + save - process_newly_available_git_data: accept optional write_policy and rejected_events_index, pass them through to process_purgatory_announcements - handle_receive_pack: accept Arc<Nip34WritePolicy> and Arc<RejectedEventsIndex>, pass them to process_newly_available_git_data - HttpService / run_server: carry the two new fields, clone into each handle_receive_pack call - main.rs: obtain rejected_events_index from sync_manager before moving it into its task; wrap write_policy in Arc for the HTTP server - RealSyncContext::process_newly_available_git_data: pass None for both new params (purgatory sync path already handles this via SyncManager::process_event_static) Also rewrite the maintainer_reprocessing integration tests to correctly exercise the hot-cache path now that announcements require git data before being released from purgatory: - Start relay_b with relay_a as bootstrap so its SyncManager syncs maintainer announcements via negentropy before the owner git push - Use push_unique_git_data_to_relay (new helper) to give each maintainer a distinct commit hash, preventing git from skipping pack transfer - Make wait_for_event_on_relay poll in a retry loop so transient timing gaps between DB write and query do not cause false negatives
2026-02-18Revert "feat: upgrade repo to Full sync and trigger PR event subscription ↵DanConwayDev
after announcement promotion" This reverts commit d76003b629a4a03dba23a8a1c41da6e4ac4c30cf.
2026-02-18feat: upgrade repo to Full sync and trigger PR event subscription after ↵DanConwayDev
announcement promotion When git data arrives for a purgatory announcement and promotes it to the database, the relay now: 1. Upgrades the announcement's sync level in RepoSyncIndex from StateOnly to Full (git/sync.rs: process_purgatory_announcements) 2. Sends AddFilters actions to SyncManager for all connected relays, using Full sync filters (Layer 2 #a/#A/#q) to subscribe to PR events (purgatory/sync/context.rs: RealSyncContext.process_newly_available_git_data) 3. For user-submitted purgatory announcements, registers the repo in RepoSyncIndex with StateOnly level and sends AddFilters to SyncManager so it discovers and connects to relays listed in the announcement tags (nostr/builder.rs: handle_announcement AcceptPurgatory path) The RealSyncContext now accepts optional repo_sync_index and sync_action_tx parameters. main.rs wires these up from SyncManager. PolicyContext gains repo_sync_index and sync_action_tx fields for the write policy path.
2026-02-17docs: clarify why fetch_repository_data excludes purgatoryDanConwayDev
Add comments explaining that PR event processing (both incoming and purgatory) should only use database announcements, not purgatory ones. This is intentional because: - Incoming PR events should only be accepted for validated announcements - Purgatory PR events should only be released when announcement is promoted - This prevents accepting PR events for announcements that fail validation Differs from state event processing which uses fetch_repository_data_with_purgatory because state events check authorization without releasing from purgatory.
2026-02-17fix: include purgatory announcements in state event authorizationDanConwayDev
When processing state events from purgatory, we need to check authorization against announcements that may still be in purgatory (not yet promoted to the database). Previously, process_purgatory_state_events() used fetch_repository_data() which only queries the database. This caused authorization failures when: 1. Git data arrives 2. Announcement is promoted from purgatory to database 3. State events are processed from purgatory 4. But db_repo_data was fetched BEFORE the announcement promotion Now uses fetch_repository_data_with_purgatory() to include both database and purgatory announcements, ensuring authorization works correctly regardless of promotion timing.
2026-02-13feat: implement announcement purgatory core (breaks archive sync test)DanConwayDev
Route new announcements to purgatory instead of accepting immediately. Announcements are promoted to the database when git data arrives, ensuring we only serve announcements for repos with actual content. Implemented: - AnnouncementPurgatoryEntry type and DashMap store - Route new announcements to purgatory (replacement announcements skip) - Promote announcements on git data arrival (process_purgatory_announcements) - Authorization checks purgatory announcements (fetch_repository_data_with_purgatory) - State policy uses purgatory announcements for maintainer validation - Cleanup task handles announcement expiry - Updated count()/cleanup() to 3-tuples Known broken: - test_archive_read_only_creates_bare_repo fails: sync module does not treat purgatory announcements as confirmed repos, so per-repo sync (state events, PRs) is never triggered for purgatory announcements - Announcement persistence (save/restore) not implemented - SyncLevel (StateOnly vs Full) not implemented - Soft expiry two-phase not implemented - Expiry extension on state event / git auth not wired up
2026-02-03Reduce log noise: change per-ref updates to DEBUG levelDanConwayDev
Only the final summary 'Aligned repository with state' remains at INFO level, showing the total count of refs_created/refs_updated/refs_deleted.
2026-01-09feat: implement state event authorization per GRASP-01 specDanConwayDev
Add comprehensive authorization checks to ensure state events are only accepted from maintainers of accepted repository announcements. This implements the core GRASP-01 requirement that pushes must match the latest state announcement "respecting the maintainer set." Changes: 1. StatePolicy authorization (src/nostr/policy/state.rs): - Check authorization BEFORE git data validation (fail-fast) - Reject if no announcement exists for repository - Reject if author not in maintainer set - Use existing helpers: fetch_repository_data() and pubkey_authorised_for_repo_owners() - Structured logging for all rejections 2. Purgatory invalidation (src/nostr/builder.rs): - New method: check_purgatory_state_events_for_identifier() - Called when announcements accepted (Accept and AcceptMaintainer) - Re-evaluates state events in purgatory for the identifier - Processes newly-authorized events (releases from purgatory) - Keeps unauthorized events for natural expiry (30 min) - Enables retroactive authorization when announcements arrive late 3. Purgatory sync authorization (src/git/sync.rs): - Check authorization BEFORE processing git data - Remove unauthorized events from purgatory (permanent rejection) - Prevents processing even if git data arrives first - Structured logging for monitoring 4. Rejected events tracking (src/sync/rejected_index.rs): - Add support for tracking rejected state events - New methods: add_state(), contains_state() - Separate metrics for state rejections - Enables sync to avoid re-fetching rejected states 5. Sync metrics (src/sync/metrics.rs, src/sync/mod.rs): - Add state-specific metrics (hot cache, cold index) - Track rejected states separately from announcements - Support monitoring of authorization rejections 6. Comprehensive tests (tests/state_authorization.rs): - test_reject_state_without_announcement - test_reject_state_from_unauthorized_author - test_accept_state_from_announcement_author - test_accept_state_from_maintainer Security Impact: - Before: State events could be published by anyone - After: Only maintainers can publish state events - Defense-in-depth: Authorization checked at 3 points: 1. On arrival (StatePolicy) 2. On announcement acceptance (purgatory re-evaluation) 3. On git data arrival (purgatory sync) All tests pass: - 248 unit tests - 51 NIP-34 announcement tests - 4 new state authorization tests - 9 rejected index tests Closes: State authorization requirement from GRASP-01 spec
2026-01-08chore: upgrade nostr-* packages to rev 4767ad13DanConwayDev
- Update nostr-relay-builder, nostr-sdk, nostr-lmdb to latest revision - Update grasp-audit nostr-sdk dependency - Fix clippy warnings: - Replace .clone() with std::slice::from_ref() in src/git/sync.rs - Change &PathBuf to &Path in tests/common/git_server.rs - Replace vec![] with array literal in src/purgatory/sync/functions.rs - Update PR_TEST_COMMIT_HASH in grasp-audit due to event generation changes All 249 tests passing, no breaking changes required.
2026-01-08chore: cargo fmtDanConwayDev
2026-01-07refactor: unify event processing logicDanConwayDev
Eliminates code duplication by extracting core event processing into reusable functions. All state and PR event processing now uses the same unified logic from src/git/process.rs. Changes: - Add src/git/process.rs with unified processing functions - process_state_with_git_data() for state events - process_pr_with_git_data() for PR events - Pure functions with comprehensive result types - Refactor policy handlers to use unified processing - src/nostr/policy/state.rs: Remove ~70 lines of duplicated logic - src/nostr/policy/pr_event.rs: Remove ~40 lines of duplicated logic - Refactor purgatory processing to use unified functions - src/git/sync.rs: Remove ~125 lines of duplicated logic - Make extract_owner_from_repo_path() public for reuse Benefits: - DRY: Single source of truth for event processing - Testable: Pure functions with clear contracts - Maintainable: Changes happen in one place - Consistent: All code paths use same logic All 217 unit tests + 40 integration tests pass (257/257).
2026-01-07fix: resolve clippy warningsDanConwayDev
- Prefix unused variable auth_result with underscore - Prefix unused field git_data_path with underscore in Purgatory struct - Add #[allow(clippy::too_many_arguments)] to handle_receive_pack - Replace len() >= 1 with !is_empty() - Replace .last() with .next_back() on DoubleEndedIterator - Fix doc list item overindentation - Replace map_or(true, ...) with is_none_or(...) - Replace map_or(false, ...) with is_some_and(...)
2026-01-07purgatory: more robust process_purgatory_state_events syncingDanConwayDev
2026-01-07purgatory: improve process_newly_available_git_data state event syncDanConwayDev
2026-01-07Add unified process_newly_available_git_data functionDanConwayDev
Implement the unified function that handles all post-git-data-available processing, regardless of how data arrived (git push or purgatory sync). This function: - Discovers satisfiable events from purgatory (state and PR events) - Syncs OIDs to authorized owner repos - Aligns refs and sets HEAD - Saves events to database - Notifies WebSocket subscribers - Removes from purgatory New additions: - ProcessResult struct for tracking processing outcomes - process_newly_available_git_data async function in src/git/sync.rs - Helper functions: extract_identifier_from_repo_path, extract_identifier_from_pr_event - Purgatory::find_prs_for_identifier method for PR event discovery - Unit tests for all helper functions Also fixes: - Simplified extract_domain to avoid url crate dependency - Removed unused imports in sync/loop.rs
2026-01-05sync PR refs to all relivant reposDanConwayDev
2026-01-05sync PR refs (refs/nostr/<event-id>) to all owner repos when push receivedDanConwayDev
When a push to refs/nostr/<event-id> is received (PR data), the git data is now synced to all other owner repositories that share maintainers with the source owner. This mirrors the behavior added for state event data. Changes: - Add sync_pr_refs_to_owner_repos() function in git/sync.rs - Add PrSyncResult struct to track sync statistics - Add copy_single_commit_between_repos() helper function - Call PR sync in handle_receive_pack after successful push - Add unit test for PrSyncResult default values
2026-01-05sync all repos when authorised state data push receivedDanConwayDev