diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-10 12:52:32 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-10 13:03:40 +0000 |
| commit | aae452697d152694a8f163219f707356e84b420b (patch) | |
| tree | 0f7e5fcaa5a005aeec7ae2d9f35b2c473ef8f785 | |
| parent | 3383477386916e82a19fa1e9c4d95b232ba0a40e (diff) | |
docs: update documentation for non-interactive mode
Add maintainer-model architecture documentation.
Update README to reflect non-interactive default behavior.
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | docs/architecture/maintainer-model.md | 84 |
2 files changed, 85 insertions, 1 deletions
| @@ -41,7 +41,7 @@ for code collaboration, nostr is used for: | |||
| 41 | - state (ie. git refs) | 41 | - state (ie. git refs) |
| 42 | - proposals (PRs), issues and related discussion | 42 | - proposals (PRs), issues and related discussion |
| 43 | 43 | ||
| 44 | a git server is still required for data storage and syncing state. multiple git servers can be used for reduncancy and they can be seemlessly swapped out by maintainers just like nostr relays. | 44 | a git server is still required for data storage and syncing state. multiple git servers can be used for reduncancy and they can be seemlessly swapped out by maintainers just like nostr relays. see [maintainer model](docs/architecture/maintainer-model.md) for details on how multi-maintainer repositories work. |
| 45 | 45 | ||
| 46 | eg self-hosted, github, codeberg, etc. | 46 | eg self-hosted, github, codeberg, etc. |
| 47 | 47 | ||
diff --git a/docs/architecture/maintainer-model.md b/docs/architecture/maintainer-model.md new file mode 100644 index 0000000..9aebea7 --- /dev/null +++ b/docs/architecture/maintainer-model.md | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | # Maintainer Model | ||
| 2 | |||
| 3 | How ngit handles multi-maintainer repositories: coordinate discovery, maintainer sets, and the distinction between shared metadata and personal infrastructure. | ||
| 4 | |||
| 5 | ## Coordinate Discovery | ||
| 6 | |||
| 7 | A **coordinate** is a `(kind, pubkey, identifier)` tuple that uniquely identifies a repository on nostr. The pubkey in the coordinate is the **trusted maintainer** (typically the original creator). | ||
| 8 | |||
| 9 | ngit discovers the coordinate locally from (in priority order): | ||
| 10 | |||
| 11 | 1. `nostr://` git remotes | ||
| 12 | 2. `nostr.repo` git config | ||
| 13 | 3. `maintainers.yaml` | ||
| 14 | |||
| 15 | No network access is required to find the coordinate. The coordinate may exist without a corresponding announcement event on relays. | ||
| 16 | |||
| 17 | ## Maintainer Set | ||
| 18 | |||
| 19 | Each repository announcement (kind 30617) contains a `maintainers` tag listing public keys. These form a recursive set: if Alice lists Bob, and Bob lists Carol, then {Alice, Bob, Carol} are all in the maintainer set. | ||
| 20 | |||
| 21 | Each maintainer independently decides who they list. Adding someone to your maintainers tag is an invitation to co-maintain. | ||
| 22 | |||
| 23 | ## Consuming vs Publishing | ||
| 24 | |||
| 25 | The key architectural distinction is between **consuming** repository data (fetching, cloning, listing) and **publishing** it (`ngit init`). | ||
| 26 | |||
| 27 | ### Consuming: Union Across Maintainers | ||
| 28 | |||
| 29 | When consuming repo data, `relays`, `clone` (git server URLs), and `blossoms` are **unioned** across all maintainers' announcement events. This means any maintainer can add a mirror git server or relay and all users benefit automatically. | ||
| 30 | |||
| 31 | ### Publishing: Personal Infrastructure, Shared Metadata | ||
| 32 | |||
| 33 | When publishing via `ngit init`, fields are sourced differently depending on their type: | ||
| 34 | |||
| 35 | #### Shared Metadata | ||
| 36 | |||
| 37 | Sourced from the **latest event** (by `created_at`) across the maintainer set: | ||
| 38 | |||
| 39 | - `name` | ||
| 40 | - `description` | ||
| 41 | - `web` | ||
| 42 | - `hashtags` | ||
| 43 | |||
| 44 | Rationale: these are shared identity. If any maintainer updates the project name, all subsequent re-announcements should pick it up. | ||
| 45 | |||
| 46 | #### Infrastructure (Personal) | ||
| 47 | |||
| 48 | Each maintainer has their own infrastructure preferences. When publishing, infrastructure comes from **my own announcement only**, not the union: | ||
| 49 | |||
| 50 | - **Grasp servers** -- where my git+nostr data is hosted. Each grasp server derives: | ||
| 51 | - Clone URL: `https://{server}/{npub}/{identifier}.git` | ||
| 52 | - Relay URL: `wss://{server}` | ||
| 53 | - Blossom URL: `https://{server}` | ||
| 54 | - **Additional relays, git servers, blossoms** -- beyond what grasp servers provide | ||
| 55 | |||
| 56 | Grasp-format clone URLs belonging to other maintainers are kept as additional git servers (they're part of the union for consumers) but are not treated as my grasp servers. | ||
| 57 | |||
| 58 | #### Maintainers | ||
| 59 | |||
| 60 | Sourced from **my own announcement only**. Each maintainer independently decides who they list. | ||
| 61 | |||
| 62 | If I don't have an existing announcement (first time co-maintaining), the default is `[me, trusted_maintainer]`. | ||
| 63 | |||
| 64 | #### Earliest Unique Commit | ||
| 65 | |||
| 66 | Cascade: my own event's value, then other maintainers' values, then the local root commit. A mismatch between maintainers may indicate a fork. | ||
| 67 | |||
| 68 | #### Identifier | ||
| 69 | |||
| 70 | From the existing coordinate. Cannot change without `--force` (changing it creates a new repository). | ||
| 71 | |||
| 72 | ## Init States | ||
| 73 | |||
| 74 | When `ngit init` runs, there are 5 possible states based on what exists locally and on relays: | ||
| 75 | |||
| 76 | | State | Condition | Behavior | | ||
| 77 | |-------|-----------|----------| | ||
| 78 | | **Fresh** | No coordinate found | Must provide name + server infrastructure | | ||
| 79 | | **Coordinate Only** | Coordinate exists, no announcement on relays | Requires `--force` (could be a relay/network issue) | | ||
| 80 | | **My Announcement** | Announcement exists, I'm the trusted maintainer | Re-publish/update, no force needed | | ||
| 81 | | **Co-Maintainer** | Announcement exists, I'm listed as maintainer | Publish own announcement, no force needed | | ||
| 82 | | **Not Listed** | Announcement exists, I'm not in maintainer set | Requires `--force` | | ||
| 83 | |||
| 84 | See `src/bin/ngit/sub_commands/init.rs` (`InitState` enum) and `tests/ngit_init.rs` for the implementation and test coverage. | ||