Separate NEG and transient-REQ semaphores did not account for persistent live REQs or each other, so individually safe limits could overdraw one relay subscription cap. Exact-ID purgatory recovery also used an SDK fetch path outside transient accounting. Adaptive pagination increased page pressure, while nostream can advertise only ten subscriptions rather than the fallback twenty.
Introduce one per-session ledger sized from NIP-11 max_subscriptions, falling back to B=20 with two reserved slots. NEG rounds, managed transient REQs, pagination verification and fallback pages, exact-ID purgatory polls, and persistent live groups all borrow from that ledger while retaining narrower class caps. Retired semaphores are closed and every acquisition carries a generation checked immediately before the SDK request, so queued or late consumers cannot send on a replacement session under obsolete accounting.
Live L1+L2+L3 filters are byte/filter-count grouped and reserved as one transaction on reconnect and consolidation. A known-too-large replacement keeps existing coverage and defers new/history work. Runtime replacement failure closes the partial target and restores the exact previous filter grouping. Unexpected live CLOSED carries its subscription identity and session generation to the actor, which ignores stale notifications and transactionally recomputes complete desired coverage.
Auto-close EOSE enqueues CLOSE before release. Because NIP-01 CLOSE has no acknowledgement, deadline recovery sends CLOSE and forces connection teardown before returning slots; the manager then reconnects normally. The first expired watchdog atomically claims teardown, closes and advances the session ledger before awaiting disconnect, and suppresses sibling watchdog actions. A production soak showed legitimate relay.ngit.dev startup pages exceeding the original 30-second deadline and three teardowns within one minute, so the fixed deadline is 120 seconds: long enough for observed valid work while retaining bounded recovery. Exact-ID fetches hold transient and ledger capacity for the complete SDK future.
Correctness assumes NIP-11 max_subscriptions describes the shared connection cap and that omission is safely represented by B=20. Advertised lower limits are honoured exactly, including nostream-shaped B=10. max_limit remains excluded from pagination sizing. When complete live coverage consumes all usable slots, the reserved margin remains outside the ledger and historic work defers. Multi-connection sharding and message-budget negotiation remain out of scope.
Tests cover fallback and advertised arithmetic, B=10 live saturation, common-helper stale waiters across session reset, exact replacement restoration after controlled third-group failure, live CLOSED generation propagation, watchdog teardown progress, simultaneous watchdog single ownership with immediate admission closure, the 120-second deadline, combined live/NEG/historic/dependency consumers, and actual purgatory polling queueing and ledger deferral. The fixed-five proxy proves transient concurrency only, not every unified-ledger consumer.
Validation after the watchdog correction: cargo test --lib (638 passed); focused relay-connection tests (38 passed); standalone startup_historic_sync_stays_within_relay_req_concurrency_limit (passed, 26.46s); nix build .#ngit-grasp (passed, /nix/store/yb1y6dr6zr34c7jny40qlrwf3611bya2-ngit-grasp-2.0.0). Four default-parallel full sync-file runs passed; two others failed only the unrelated unresolved_repositories_share_one_dependency_poll_per_relay load-sensitive assertion while both concurrency scenarios passed. That test passed 5/5 standalone on this tree and 5/5 on clean master, then reproduced with the same assertion/query signature in the third comparable full sync-file control on clean master 6cccebb. The watchdog cannot execute in its approximately three-second scenario, so no batching behavior was changed.
ngit-grasp Documentation
Welcome to the ngit-grasp documentation! We use the Diátaxis framework to organize our documentation into four types, each serving a different purpose.
PRACTICAL THEORETICAL
───────── ───────────
LEARNING │ Tutorials │ Explanation │
│ │ │
│ Getting │ Architecture │
│ Started │ Decisions │
│ │ │
├────────────────┼──────────────────┤
│ │ │
WORKING │ How-To │ Reference │
│ Guides │ │
│ │ API Docs │
│ Deployment │ Protocols │
│ Testing │ │
│ │ │
📚 Documentation Types
🎓 Tutorials - Learning by Doing
Purpose: Learn the basics through practical steps
For: Newcomers getting started
Style: Step-by-step lessons with guaranteed outcomes
- Getting Started - Your first ngit-grasp setup
- Running Your First Audit - Using grasp-audit tool
🔧 How-To Guides - Solving Problems
Purpose: Accomplish specific tasks
For: Users with basic knowledge solving real problems
Style: Practical recipes and solutions
- Deploy ngit-grasp - Production deployment guide
- Configure Nix Flakes - Nix development environment
- Run Compliance Tests - GRASP compliance testing
- Upgrade nostr-sdk - Handling SDK upgrades
📖 Reference - Technical Information
Purpose: Look up technical details
For: Users who know what they're looking for
Style: Dry, factual, comprehensive
- Git Protocol - Git Smart HTTP protocol details
- GRASP Protocol - GRASP specification details
- Configuration - All config options
- API Reference - Internal API documentation
💡 Explanation - Understanding Concepts
Purpose: Understand the "why" and design decisions
For: Users wanting deeper understanding
Style: Discussion, context, alternatives
- Architecture Overview - System design and components
- Inline Authorization - Why we chose this approach
- Comparison with ngit-relay - How we differ from reference
- Design Decisions - Key architectural choices
🚀 Quick Start Paths
I'm brand new to ngit-grasp
- Read README.md for project overview
- Follow Getting Started Tutorial
- Understand Architecture Overview
I want to deploy ngit-grasp
- Review Configuration Reference
- Follow Deployment How-To
- Set up monitoring and backups
I want to develop on ngit-grasp
- Follow Getting Started Tutorial
- Read Architecture Overview
- Check Nix Flakes How-To
- Review Test Strategy
I want to understand the design
- Read Inline Authorization Explanation
- Review Design Decisions
- Compare with ngit-relay Comparison
I'm looking for specific information
- Protocol details? → Reference
- Configuration options? → Configuration Reference
- Git protocol? → Git Protocol Reference
📂 Additional Resources
Archive
Historical session notes and completed work. Useful for understanding project evolution but not required reading.
Learnings
DEPRECATED - Being migrated to Diátaxis structure:
- Gotchas → How-To Guides
- Patterns → Reference or Explanation
- Notes → Appropriate category
🤝 Contributing to Documentation
When adding documentation, ask yourself:
Is it a tutorial?
- Does it teach a beginner?
- Is it a complete lesson with guaranteed outcome?
- → Add to
tutorials/
Is it a how-to guide?
- Does it solve a specific problem?
- Is it a recipe for accomplishing a task?
- → Add to
how-to/
Is it reference material?
- Is it technical information?
- Will people look it up when needed?
- → Add to
reference/
Is it explanation?
- Does it explain "why"?
- Does it discuss alternatives or design?
- → Add to
explanation/
See Diátaxis documentation for more guidance.
📊 Project Status
ALPHA - Under active development. Core functionality working, API may change.
Completed
- ✅ grasp-audit compliance testing tool
- ✅ Nix flake development environment
- ✅ nostr-sdk 0.43 upgrade
- ✅ Documentation restructure (Diátaxis)
In Progress
- 🔄 Core ngit-grasp server implementation
- 🔄 GRASP-01 compliance
Planned
- 🔜 GRASP-02 (Proactive Sync)
- 🔜 GRASP-05 (Archive)
🔗 External Links
Documentation structure based on Diátaxis
Last updated: November 4, 2025