Files
ngit-grasp/docs
DanConwayDev d3d905010c fix(grasp06): narrow /prs/ per-path lock, gate cleanup on in-flight count
The previous design held the per-(submitter, identifier) mutex for the
entire receive-pack pipeline — `git init --bare`, the pack upload from
the client, `git-receive-pack`, per-ref validation, and the zero-ref
cleanup. Two concurrent pushes to the same `/prs/<submitter>/<id>.git`
path were therefore fully serialised end-to-end, with the second push's
HTTP connection blocked on the mutex for the entire duration of the
first push (including its pack upload over the wire). With multiple
agents or CI jobs sharing a contributor identity this could produce
HTTP/proxy timeouts and apparently-stuck pushes for no good reason —
git's own ref locking would normally handle intra-push concurrency on
the same path just fine.

Switch to a `PrsPathState { mu: Mutex<()>, in_flight: AtomicUsize }`
per path. The receive handler now takes the mutex only briefly:

  * at the start of the request to run `git init --bare` and bump
    `in_flight` from 0 to 1, then release the mutex,
  * at the end of the request to drop `in_flight` and, if it lands on
    zero with the repo at zero refs, `rm -rf` the bare directory.

`git-receive-pack` and per-ref validation run with no per-path lock
held, so concurrent pushes by different agents to the same path proceed
in parallel.

Off-push cleanup paths (the PR-event policy when it discards a scoped
placeholder whose incoming event mismatches, and the purgatory expiry
sweep when a scoped placeholder times out) take the same mutex briefly,
delete the dangling ref, then remove the bare directory only when
`in_flight.load() == 0` and `list_refs` is empty. With both reads
performed under the mutex that gates `in_flight` mutations, a repo
deletion can never race a push that is mid-receive: either the push is
still in init/register and we wait on the mutex, or the push has
already incremented `in_flight` (so we read non-zero and skip), or the
push has finished and decremented (so the directory is genuinely idle).

The end-of-push cleanup now also runs when receive-pack returns a
protocol-error response (200 with ERR pkt-line), which the previous
code's early-return skipped — a probe push that failed git-level
validation after `ensure_repo_initialised` had created the directory
used to leak an empty `.git` dir, which now gets removed in the same
critical section.

A small `path_state(&locks, path)` helper centralises the
get-or-insert-Arc dance the three sites used to duplicate.

Docs updated:

  * docs/explanation/grasp-06-contributor-pr-submission.md — replace
    the "lock held for the entire push pipeline" paragraph with the
    new mutex + `in_flight` discipline; update the three-sites
    enumeration to describe the `in_flight == 0` guard.
  * docs/explanation/architecture.md — same shape, one-paragraph.
  * docs/how-to/enable-grasp-06.md — call out that the mutex is held
    only briefly so concurrent pushes don't serialise.
2026-05-15 19:15:42 +00:00
..
2025-11-04 10:25:53 +00:00
2025-11-04 10:25:53 +00:00

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

🔧 How-To Guides - Solving Problems

Purpose: Accomplish specific tasks
For: Users with basic knowledge solving real problems
Style: Practical recipes and solutions

📖 Reference - Technical Information

Purpose: Look up technical details
For: Users who know what they're looking for
Style: Dry, factual, comprehensive

💡 Explanation - Understanding Concepts

Purpose: Understand the "why" and design decisions
For: Users wanting deeper understanding
Style: Discussion, context, alternatives


🚀 Quick Start Paths

I'm brand new to ngit-grasp

  1. Read README.md for project overview
  2. Follow Getting Started Tutorial
  3. Understand Architecture Overview

I want to deploy ngit-grasp

  1. Review Configuration Reference
  2. Follow Deployment How-To
  3. Set up monitoring and backups

I want to develop on ngit-grasp

  1. Follow Getting Started Tutorial
  2. Read Architecture Overview
  3. Check Nix Flakes How-To
  4. Review Test Strategy

I want to understand the design

  1. Read Inline Authorization Explanation
  2. Review Design Decisions
  3. Compare with ngit-relay Comparison

I'm looking for specific information


📂 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)


Documentation structure based on Diátaxis
Last updated: November 4, 2025