Files
ngit-grasp/6af6-archive-read-only-should-create-bare-repos.md
T

8.2 KiB

archive_read_only Should Create Bare Git Repositories

ID: 6af6

Problem

When archive_read_only = true is set with archive_all = true, the relay accepts repository announcements but does NOT create bare git repositories or sync git data. This is a bug.

Current behavior:

  • src/nostr/builder.rs:179 explicitly skips bare repository creation for AcceptArchive announcements
  • Comment says: "Don't create bare repository for archived announcements"
  • Result: /persistent/grasp/full-archive/git/ directory is empty despite accepting announcements

Expected behavior:

  • archive_read_only = true should:
    • ✅ Accept repository announcements (working)
    • ✅ Create bare git repositories (BROKEN)
    • ✅ Sync git data from remote clone URLs (BROKEN)
    • ❌ Reject git pushes (working - read-only)

Impact:

  • Archive relays cannot actually archive git repositories
  • Only Nostr events are stored, not the actual git data
  • Defeats the purpose of GRASP-05 archive mode

Plan

  • Phase 1: Fix bare repository creation for archive mode
    • Remove the skip logic in src/nostr/builder.rs:179
    • Ensure bare repos are created for AcceptArchive announcements
    • Verify sync works for archived repos
  • Phase 2: Add test coverage
    • Create integration test for archive_read_only mode
    • Verify bare repos are created
    • Verify git data is synced
    • Verify pushes are rejected
  • Phase 3: Update documentation
    • Clarify archive_read_only behavior in docs
    • Add examples of proper archive configuration

Progress

2026-01-19 [Session 13:20]

  • Identified bug: archive_read_only skips bare repo creation
  • Root cause: Line 179 in src/nostr/builder.rs explicitly skips creation
  • User reported empty /persistent/grasp/full-archive/git/ directory
  • Created issue to track fix

2026-01-19 [Session 14:45]

  • Started work: Created worktree 6af6-archive-read-only-should-create-bare-repos
  • Ready to begin test creation and implementation

2026-01-19 [Session 15:30]

  • FIXED: Modified src/nostr/builder.rs:169-208 to create bare repos for AcceptArchive
  • FIXED: Modified src/config.rs:564-575 to respect custom git_data_path in memory backend
  • COMPLETED: Test tests/archive_read_only.rs now passes bare repo creation check
  • REMAINING: Git sync not working yet - repos created but data not synced from clone URLs
  • Decision: Bare repo creation bug is FIXED. Git sync is a separate issue that needs investigation
  • All unit tests pass (369 passed)
  • Changes:
    • AcceptArchive now calls ensure_bare_repository() just like Accept does
    • Memory backend respects NGIT_GIT_DATA_PATH when explicitly set (fixes test isolation)
    • Added test coverage for memory backend path behavior

2026-01-19 [Session 16:00]

  • ROOT CAUSE FOUND: Git sync not triggered for archive announcements
    • Purgatory sync requires events in purgatory to trigger (state/PR events)
    • Archive announcements have NO purgatory events initially
    • has_pending_events() returns false → sync skipped
    • collect_needed_oids() returns empty → sync skipped
  • SOLUTION: Added direct git fetch for archive announcements
    • Created AnnouncementPolicy::sync_archive_git_data() method
    • Spawns async task to fetch all refs from clone URLs
    • Uses git fetch +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*
    • Tries each clone URL until one succeeds
  • COMPLETED: All tests pass (369 unit + all integration tests)
    • test_archive_read_only_creates_bare_repo now fully passes
    • Bare repo created ✅
    • Git data synced ✅
    • Pushes rejected ✅
  • Changes:
    • src/nostr/policy/announcement.rs:111-205: Added sync_archive_git_data() method
    • src/nostr/builder.rs:193-216: Spawn sync task for AcceptArchive announcements
    • Archive mode now works end-to-end: accepts announcements, creates repos, syncs git data

2026-01-19 [Session 17:00]

  • COMPLETED: Issue fully resolved and documented
  • Documentation Updated: docs/reference/configuration.md
    • Added clarification that archive_read_only DOES create bare repos
    • Added clarification that git data IS synced from clone URLs
    • Added "Git Sync Behavior" section with technical details
    • Updated use case examples to show expected results
  • Test Coverage: Comprehensive integration test added
    • tests/archive_read_only.rs: Tests bare repo creation, git sync, and push rejection
    • All 369 unit tests pass
    • All integration tests pass
  • Summary of Fix:
    • Bug: archive_read_only was accepting announcements but NOT creating repos or syncing git data
    • Root cause: Explicit skip logic in builder.rs + no sync trigger for archive announcements
    • Solution: Remove skip logic + add direct git fetch for archive announcements
    • Result: Archive mode now fully functional - accepts, creates, syncs, and enforces read-only
  • All phases complete: Ready to commit and close issue

2026-01-19 [Session 18:30] - ARCHITECTURE RETHINK

  • PROBLEM IDENTIFIED: Previous sync_archive_git_data() approach was wrong
    • Direct git fetch from clone URLs trusts git servers blindly
    • No validation against Nostr events (state events)
    • Bypasses the security model of purgatory sync
    • "Naughty git servers" could provide incorrect state
  • CORRECT ARCHITECTURE: Use existing purgatory sync infrastructure
    • Archive relay syncs from bootstrap relay (relay-to-relay sync)
    • State events are synced via negentropy/REQ
    • State events go to purgatory (waiting for git data)
    • Purgatory sync fetches git data from clone URLs
    • Git data is validated against Nostr state events
  • CHANGES MADE:
    • Removed sync_archive_git_data() method from src/nostr/policy/announcement.rs
    • Removed spawn of custom sync in src/nostr/builder.rs
    • Updated test to use relay-to-relay sync (TestRelay with bootstrap_relay_url)
    • Made TestRelay::start_with_archive_and_sync() public for tests
  • TEST UPDATES:
    • test_archive_read_only_creates_bare_repo: Now uses source relay + archive relay
    • test_archive_without_state_events_does_not_sync_git: Verifies security model
    • All 369 unit tests pass
    • All archive integration tests pass
  • SECURITY MODEL:
    • Archive mode only syncs git data when there are state events to validate against
    • This protects against "naughty git servers" providing incorrect state
    • Same security guarantees as normal relay operation
  • LIMITATION DOCUMENTED:
    • Archive mode requires a bootstrap relay to sync state events
    • Without state events, git data is NOT synced (by design - security)

2026-01-19 [Session 19:00] - READY FOR MERGE

  • SQUASHED COMMITS: All 4 commits squashed into single comprehensive commit
    • Commit: f191261 "fix: archive_read_only creates bare repos and syncs git data (GRASP-05)"
    • Comprehensive commit message includes problem, root cause, solution, security model, test coverage
  • ALL TESTS PASS: 37 tests passed (including both archive integration tests)
    • test_archive_read_only_creates_bare_repo: End-to-end sync flow verified
    • test_archive_without_state_events_does_not_sync_git: Security model verified
  • READY FOR REVIEW AND MERGE:
    • Single clean commit for easy review
    • Comprehensive test coverage
    • Documentation updated
    • Security model validated
    • All phases complete

2026-01-19 [Session 20:00] - FINAL REVIEW AND MERGE

  • BUILD AGENT REVIEW: Reviewed test implementation for quality and isolation
    • Test isolation: ✅ Uses random temp directories and ports - no conflicts possible
    • Test complexity: ✅ Bare repo check is necessary and justified - validates the actual fix
    • Recommendation: Keep current implementation - well-designed and ready to merge
  • ISSUE COMPLETE: All work committed, tests pass, ready to merge to main
    • Commit bf70d72: "fix: archive_read_only creates bare repos for archived announcements"
    • Test coverage comprehensive and properly isolated
    • No changes needed - merging to main

Notes

  • Related code: src/nostr/builder.rs:169-195 (AcceptArchive handling)
  • Related code: src/nostr/events.rs:434-437 (GRASP-05 validation)
  • User configuration: NixOS with archiveAll = true and archiveReadOnly = true
  • Test should verify both event storage AND git repository creation