DanConwayDev d428baf30f docs: one-prompt architecture plan
ok 2 prompts, the second one was about the test strategy so we could
reuse it. I was thinking of a tool like blossom audit. but i didnt
mention it specifically.
2025-11-03 17:02:31 +00:00
2025-11-03 17:02:31 +00:00
2025-11-03 17:02:31 +00:00
2025-11-03 17:02:31 +00:00

ngit-grasp

A GRASP (Git Relays Authorized via Signed-Nostr Proofs) implementation in Rust.

Overview

ngit-grasp is a Rust-based implementation of the GRASP protocol, which enables decentralized Git repository hosting with Nostr-based authorization. This implementation combines:

  • Git Smart HTTP Backend: Serves Git repositories over HTTP
  • Nostr Relay: Stores and validates repository announcements and state events
  • Integrated Authorization: Validates Git pushes against Nostr state events without requiring external hooks

Unlike the reference implementation (ngit-relay) which uses nginx + git-http-backend + pre-receive hooks + Khatru (Go), ngit-grasp provides a unified Rust service that handles both Git and Nostr protocols natively.

Status

ALPHA - Under active development. API and architecture subject to change.

Key Features

  • Pure Rust Implementation: Single binary, no external dependencies beyond Git itself
  • Integrated Authorization: Push validation happens inline during the Git receive-pack operation
  • GRASP-01 Compliant: Core service requirements for Git hosting with Nostr authorization
  • Extensible Architecture: Designed to support GRASP-02 (Proactive Sync) and GRASP-05 (Archive) extensions
  • Developer-Friendly: Built with modern Rust async patterns using tokio and actix-web

Architecture Highlights

The key architectural decision is inline authorization rather than Git hooks:

  • The git-http-backend crate provides low-level access to the Git protocol
  • We intercept the git-receive-pack operation before spawning the Git process
  • Push validation happens by checking the Nostr relay for the latest state event
  • Only matching pushes are forwarded to the actual Git repository

This approach provides:

  • Better error messages: Direct HTTP responses vs. hook stderr
  • Simpler deployment: No hook management or symlinks
  • Tighter integration: Shared state between Git and Nostr components
  • Easier testing: Pure Rust unit and integration tests

GRASP Compliance

GRASP-01 (Core Service Requirements)

  • ✅ NIP-01 compliant Nostr relay at /
  • ✅ Accepts NIP-34 repository announcements and state events
  • ✅ Git Smart HTTP service at /<npub>/<identifier>.git
  • ✅ Push validation against Nostr state events
  • ✅ Multi-maintainer support via recursive maintainer sets
  • ✅ Support for refs/nostr/<event-id> for PRs
  • ✅ CORS support for web-based Git clients
  • ✅ NIP-11 relay information document

GRASP-02 (Proactive Sync) - Planned

  • 🔄 Proactive event sync from listed relays
  • 🔄 Proactive Git data sync from listed clone URLs
  • 🔄 PR data fetching and serving

GRASP-05 (Archive) - Planned

  • 🔄 Accept repositories not listing this instance
  • 🔄 Backup/mirror mode operation

Technology Stack

  • Rust: Core language
  • actix-web: HTTP server framework
  • git-http-backend: Git protocol handling
  • nostr-relay-builder: Nostr relay infrastructure from rust-nostr
  • nostr-sdk: Nostr event handling and validation
  • tokio: Async runtime

Quick Start

# Clone the repository
git clone https://gitworkshop.dev/ngit-grasp
cd ngit-grasp

# Build
cargo build --release

# Configure
cp .env.example .env
# Edit .env with your settings

# Run
cargo run --release

Configuration

Environment variables (see .env.example):

  • NGIT_DOMAIN: Your domain (e.g., gitnostr.com)
  • NGIT_OWNER_NPUB: Relay owner's npub
  • NGIT_RELAY_NAME: Relay name for NIP-11
  • NGIT_RELAY_DESCRIPTION: Relay description
  • NGIT_GIT_DATA_PATH: Path to store Git repositories
  • NGIT_RELAY_DATA_PATH: Path to store Nostr events
  • NGIT_BIND_ADDRESS: Server bind address (default: 127.0.0.1:8080)

Development

See docs/ARCHITECTURE.md for detailed architecture documentation and docs/TEST_STRATEGY.md for comprehensive testing approach.

# Run tests
cargo test

# Run compliance tests
cargo test --test compliance

# Run with logging
RUST_LOG=debug cargo run

# Check code
cargo clippy
cargo fmt --check

# Generate test coverage
cargo tarpaulin --out Html

Project Structure

ngit-grasp/
├── src/
│   ├── main.rs              # Entry point, server setup
│   ├── git/
│   │   ├── mod.rs           # Git module
│   │   ├── handler.rs       # Git HTTP handlers
│   │   └── authorization.rs # Push validation logic
│   ├── nostr/
│   │   ├── mod.rs           # Nostr module
│   │   ├── relay.rs         # Relay setup and policies
│   │   └── events.rs        # Event handlers
│   ├── storage/
│   │   ├── mod.rs           # Storage abstraction
│   │   └── repository.rs    # Repository management
│   └── config.rs            # Configuration
├── docs/
│   └── ARCHITECTURE.md      # Detailed architecture
├── tests/
│   ├── integration/         # Integration tests
│   └── fixtures/            # Test data
└── README.md

Comparison with ngit-relay

Feature ngit-relay (Go) ngit-grasp (Rust)
Language Go Rust
Components nginx + git-http-backend + hooks + Khatru Single integrated binary
Authorization Pre-receive Git hook Inline during receive-pack
Deployment Docker + supervisord Single binary
Testing Go tests + shell scripts Rust unit + integration tests
Performance Good Excellent (zero-copy, async)

Contributing

Contributions welcome! Please:

  1. Read docs/ARCHITECTURE.md
  2. Open an issue to discuss major changes
  3. Follow Rust conventions and run cargo fmt + cargo clippy
  4. Add tests for new functionality

License

MIT License - see LICENSE for details

Acknowledgments

  • Reference implementation by @DanConwayDev
  • rust-nostr team for excellent Nostr libraries
  • Git community for the Smart HTTP protocol
S
Description
No description provided
Readme MIT
27 MiB
Languages
Rust 98.6%
Nix 0.7%
Shell 0.5%
HTML 0.2%