Files
ngit-grasp/docs/explanation
DanConwayDev d0a23caf5c feat(nip34): parse indexed M/m role tags as the primary maintainer listing
Follow the indexed repository roles format from NIP-34 (nips 986edd1):
`M` (lead) and `m` (co-maintainer) tags are now the primary maintainer
listing, and their presence means the deprecated `maintainers` tag is
ignored entirely. The lead / co-maintainer distinction carries no meaning
for this service, so both collapse into one maintainer set.

Role tags may record history as alternating start/end timestamps; a tag
is currently active when it has fewer than four elements or an odd number
of elements. Ended entries are ignored entirely: role history is only
consulted to conclude that a pubkey is no longer a maintainer, never to
grant time-scoped retroactive authority over historic events. A pubkey
may appear in one `M` and one `m` tag to record a role transition and
remains a maintainer while either entry is active; a second tag under
the same letter is malformed and rejects the announcement.

RepositoryAnnouncement::listed_maintainers() - already the single source
for the listed maintainer set since the reciprocal-membership commit -
now prefers active role-tag entries over the deprecated tag, so state
authorization, replacement detection, the maintainer exception, sync
discovery and the dependency walkers all pick up the new format through
the sites switched to it here. Two refinements to membership follow from
the format:

- An announcement using role tags acknowledges its author via an active
  self-entry, or implicitly: per NIP-34 an author who appears in no role
  tag is a maintainer for the repository's entire history. Only an ended
  self-entry means the member left, which takes precedence over
  assignments in other announcements and is distinct from merely being
  invited (author_has_left).
- A `u` (subordinate fork) tag has no effect on maintainership: the
  author of a role-less announcement asserts maintainership with or
  without it.

Correctness assumption: authorization remains namespace-scoped, so the
owner of a repository namespace stays authorized for it regardless of
their own role history; role history only ends the authority of listed
maintainers. Conflicting listings across
announcements resolve as the union of confirmed members' active
listings, matching the NIP's current-role rule; the NIP's owner-first
precedence applies only to conflicting records of past roles, which
this service never evaluates.

Scope deliberately excluded: the moderator role tag (`o`) is handled in
a follow-up commit.

Validation: nostr::events and git::authorization unit tests,
state_authorization suite (including new role-tag acceptance and
ended-role rejection tests) and the sync invitation tests all pass.
2026-08-19 11:29:30 +00:00
..

Explanation

Understanding-oriented documentation - Concepts, design decisions, and the "why" behind ngit-grasp.


What Is Explanation?

Explanation documentation helps you understand concepts and design decisions, providing context and discussing alternatives.

Characteristics:

  • ✅ Understanding-oriented (clarify concepts)
  • ✅ Theoretical (ideas and design)
  • ✅ Discuss alternatives
  • ✅ Provide context and background
  • ✅ Answer "why" questions

Not explanation:

  • ❌ Step-by-step lessons (those are Tutorials)
  • ❌ Problem-solving recipes (those are How-To)
  • ❌ Technical specifications (those are Reference)

Available Explanation Documentation

Architecture Overview

Understand the system design and component interaction

Topics:

  • Overall architecture
  • Component responsibilities
  • Data flows
  • Technology choices
  • Design patterns

Read when: You want to understand how ngit-grasp works as a system


Inline Authorization

Why we validate pushes inline instead of using Git hooks

Topics:

  • The authorization problem
  • Git hooks approach
  • Inline approach
  • Comparison and trade-offs
  • Implementation details

Read when: You want to understand the core architectural decision


Design Decisions

Key architectural choices and their rationale

Topics:

  • Inline authorization vs hooks
  • Technology stack choices
  • Storage design
  • API design
  • Performance considerations

Read when: You want to know why things are the way they are


Comparison with ngit-relay

How ngit-grasp differs from the reference implementation

Topics:

  • Architecture comparison
  • Component differences
  • Trade-offs
  • Migration path
  • Compatibility

Read when: You're familiar with ngit-relay and want to understand differences


Purgatory Design

In-memory holding area for events awaiting git data

Topics:

  • The "which arrives first?" problem
  • Separate storage for state vs PR events
  • Late binding for state events
  • Bidirectional waiting for PR events
  • Authorization during push

Read when: You want to understand how ngit-grasp handles out-of-order event/git data arrival


GRASP-02 Proactive Sync

Relay-to-relay synchronization for repository discovery

Topics:

  • Negentropy-based event sync
  • Repository announcement discovery
  • Relay management and reconnection
  • Layer 2 filtering
  • Bootstrap and dynamic relay discovery

Read when: You want to understand how ngit-grasp discovers and syncs repositories across relays


GRASP-03 Proactive Sync Plus

NIP-65 inbox/outbox discovery for accepted repository conversations

Read when: You want to understand how accepted conversations are recovered from participant mailboxes


Sync Scaling Constraints and Budgets

Relay-imposed limits and how sync spends them at scale

Topics:

  • Verified relay limits (strfry, live NIP-11, our embedded relay)
  • Per-connection budget ledger (live vs historic vs fallback)
  • Byte-budgeted filter chunking and REQ packing
  • Bounded negentropy concurrency
  • Multi-connection escalation and serving-side obligations

Read when: You're changing filter construction, subscription management, or sync concurrency, and need the constraint justification


GRASP-02 Purgatory Git Data Fetching

Proactive git data fetching from remote servers

Topics:

  • Identifier-based batching
  • Exponential backoff with fresh start
  • Domain throttling (5 concurrent, 30/min)
  • Debounced delays (3min user, 500ms sync)
  • 30-minute expiry
  • Mock-based testability

Read when: You want to understand how purgatory automatically fetches missing git data


Unified Git Data Sync

Shared processing for git push and purgatory sync paths

Topics:

  • Why unify push and sync processing
  • OID syncing to owner repos
  • Ref alignment logic
  • Event release from purgatory
  • WebSocket notification

Read when: You want to understand how git data is processed consistently regardless of arrival method


Monitoring Overview

Prometheus metrics and observability

Topics:

  • Metrics philosophy
  • Connection tracking
  • Git operation metrics
  • Nostr event metrics
  • Privacy considerations

Read when: You want to understand how to monitor ngit-grasp in production


Administration, Private Analytics, and Runtime Configuration Vision

Nostr-authenticated management API, embedded UI, and layered configuration

Topics:

  • NIP-98 authentication and NIP-86-compatible methods
  • Scoped private analytics and future quota accounting
  • Embedded static administration application
  • Provenance-aware configuration and database overrides
  • Incremental live reconfiguration

Read when: You are designing administration APIs, operator tooling, runtime settings, or quota features


Defensive Measures & Rate Limiting

Protection against abuse, spam, and denial-of-service attacks

Topics:

  • Connection and subscription management
  • Event publishing rate limits
  • Content filtering (blacklists/whitelists)
  • Event validation plugin system (WritePolicy/QueryPolicy)
  • Relay health management (naughty list, exponential backoff)
  • Privacy-preserving IP tracking
  • Future enhancements (per-IP rate limiting)

Read when: You want to understand how ngit-grasp protects against abuse and what defensive features are available


GRASP-05 Archive Mode

Read-only mirroring of repositories

Topics:

  • Archive whitelist configuration
  • Archive-all mode
  • Read-only mode defaults
  • Use cases for backup/mirror relays

Read when: You want to understand how to run an archive/backup relay


GRASP-08 Private Service Authentication

Service-wide NIP-42/NIP-98 authentication for private repositories

Topics:

  • Fail-closed private mode and indistinguishable 401 responses
  • The GRASP-08 repository-scoped NIP-98 profile vs generic NIP-98
  • NIP-42 authentication outside the embedded relay
  • Service-wide membership and dynamic accepted-relay-owner admission
  • Trust model and follow-up scope

Read when: You want to understand how a private GRASP instance authenticates clients and peers


Repository Lifecycle

Handling repository removal, holding, archive, recovery, and purgatory

Topics:

  • Repository lifecycle architecture
  • Delete disrespector concept
  • Preventing left-pad scenarios
  • Archival policies
  • Holding, recovery, purgatory, and operator curation flows

Read when: You want to understand how ngit-grasp keeps nostr state and git data aligned across deletion, vanish, moderation, recovery, and purgatory flows


Identifier-family Git Object Storage

Deduplicating Git objects across related owner and contributor views

Topics:

  • Identifier-scoped object families and thin repository views
  • Anonymous receive-pack negotiation through Git alternates
  • Local-first storage with an opt-in S3 backend and bounded cache
  • No-GC rollback preservation
  • Crash-safe launch-time migration from legacy bare repositories

Read when: You are changing Git storage, /prs/ delivery, rollback retention, or server startup migration


Planned Explanation Documentation

GRASP Protocol Design

Status: 🔜 Planned

Topics:

  • Why Nostr for Git?
  • Authorization model
  • Trust and verification
  • Decentralization benefits

Testing Philosophy

Status: 🔜 Planned

Topics:

  • Why test isolation?
  • Integration vs unit tests
  • Compliance testing approach
  • Test-driven development

Performance Considerations

Status: 🔜 Planned

Topics:

  • Async architecture
  • Caching strategy
  • Database choices
  • Bottlenecks and solutions

How to Use Explanation Documentation

  1. Read to understand - Not to accomplish a task
  2. Follow your curiosity - Read what interests you
  3. Connect concepts - Link ideas together
  4. Question and explore - Think critically

Not sure if this is what you need?


Contributing Explanation Documentation

When writing explanation:

DO:

  • ✅ Discuss concepts and ideas
  • ✅ Provide context and background
  • ✅ Explain alternatives
  • ✅ Use analogies and examples
  • ✅ Connect to broader context
  • ✅ Answer "why" questions

DON'T:

  • ❌ Provide step-by-step instructions (link to Tutorials/How-To)
  • ❌ List technical details (link to Reference)
  • ❌ Assume you must be comprehensive
  • ❌ Avoid opinions (explanation can be opinionated)

Template:

# Explanation: [Topic]

**Purpose:** [What concept/decision this explains]  
**Audience:** [Who wants to understand this]

---

## The Problem/Question

[What are we trying to understand?]

---

## Background

[Context and history]

---

## Our Approach

[How we address it]

### Why This Works

[Explanation of benefits]

### Trade-offs

[What we gain and lose]

---

## Alternatives Considered

### [Alternative 1]

**Pros:**
- [Benefits]

**Cons:**
- [Drawbacks]

**Why we didn't choose it:**
[Reasoning]

---

## Conclusion

[Summary of understanding]

---

## Related Documentation
- [Links to relevant docs]

See Diátaxis: Explanation for detailed guidance.


Part of the ngit-grasp documentation using the Diátaxis framework.