10 KiB
Nostr Git Source Hosting Plan
This plan describes how Archipelago can publish and accept contributions to its
source code through ngit, NIP-34, and GRASP while keeping the developer
experience inside Archipelago.
Goals
- Publish Archipelago source from a sanitized, fresh-history repository.
- Make the in-app registry the primary onboarding path for contributors.
- Let contributors clone, branch, push PR branches, open PRs, and discuss issues with a Nostr identity from their Archipelago node.
- Follow the Bitcoin Core development model: broad public review and easy forks, with canonical merge authority held by a small maintainer set.
- Give contributors full read, fork, and proposal rights, but no direct merge rights on the canonical repository.
- Keep the official maintainer identity and merge authority separate from user node identities.
Current Building Blocks
Archipelago already has most of the primitives needed for this:
- App manifests and the app registry already install developer tooling as rootless Podman apps.
- The
giteaapp provides a conventional fallback Git UI and package registry. - The app launcher already exposes a consent-gated NIP-07 bridge for launched
apps using
getPublicKey,signEvent, NIP-04, and NIP-44 requests. - The backend exposes node and identity Nostr signing RPC methods.
- FIPS gives nodes a stable mesh identity and private transport path, but repo announcements and PRs should remain NIP-34 compatible on normal Nostr relays.
- DWN protocol registration exists and can be used later for local contribution metadata/cache, but should not be required for the first public workflow.
Protocol Basis
Use existing Nostr Git conventions rather than inventing an Archipelago-only protocol:
- NIP-34 repository announcement events identify repositories with kind
30617. - NIP-34 repository state events publish branch/tag refs with kind
30618. - NIP-34 patches, pull requests, PR updates, issues, and status events use kinds
1617,1618,1619,1621, and1630-1633. ngitprovides thegit-remote-nostrhelper fornostr://clone URLs and PR branches.- GRASP servers provide Git Smart HTTP storage while Nostr events remain the authority for repository identity, refs, PRs, issues, and maintainer state.
Primary references:
- https://nips.nostr.com/34
- https://docs.rs/crate/ngit/latest/source/README.md
- https://ngit.dev/grasp/
Recommended Architecture
Apps
Create two first-party apps:
ngit: CLI/runtime package containingngitandgit-remote-nostr.archipelago-source: web UI for cloning Archipelago source, viewing NIP-34 issues/PRs, opening branches, and submitting PR events.
The archipelago-source app should depend on ngit. It can also recommend
Gitea for users who want a conventional local web Git UI, but Gitea should not
be the source of truth for public contribution permissions.
Contributor Onboarding
When the user installs archipelago-source from the registry:
- Show a modal before first launch: "Contribute to Archipelago".
- Explain that the app will use their Archipelago Nostr identity to clone and sign contribution events.
- Display the maintainer repository announcement, clone URL, maintainer npub, and relay/GRASP endpoints.
- Ask for consent to:
- fetch repository metadata from configured relays,
- clone source through
nostr://, - create local branches,
- sign NIP-34 issue/PR/comment events,
- push PR branches to approved GRASP servers.
- Store approval per app origin, identity id, repository id, and relay set.
This should build on the existing NIP-07 app-launcher bridge, but use a more specific permission scope than the generic sign-event approval.
Identity And Permissions
Use four identity classes:
archipelago-maintainer: an offline or tightly controlled Nostr key that signs the canonical kind30617repo announcement and status/merge events.archipelago-merge-maintainer: one of the small set of maintainer npubs allowed to advance canonical refs and publish valid merged/applied status.archipelago-build: release automation key for signed release artifacts and CI status events. It must not have merge authority.contributor: user node or app-specific identity used for PRs, issues, and comments.
Contributor rights:
- Clone the repository.
- Open issues.
- Push proposal branches using
pr/<npub>/<short-topic>orpr/<event-id>. - Publish NIP-34 PR/update/comment events.
- Rebase and update their own PR branch.
- Run local validation and attach status evidence.
Contributor restrictions:
- Cannot update
refs/heads/mainor release branches in canonical state. - Cannot publish maintainer-valid merge/applied status.
- Cannot alter the canonical repository announcement.
- Cannot publish release catalog signatures.
Maintainer rights:
- Publish/update the canonical repo announcement.
- Publish canonical
refs/heads/mainstate. - Mark PRs merged/closed/draft via NIP-34 status events.
- Sign release tags and catalog updates.
Fork rights:
- Any contributor can create their own NIP-34 kind
30617repository announcement for a fork. - Fork announcements should use the NIP-34
utag to point back to the canonicalarchyrepository. - The source app should make forking a first-class path: "Fork on Nostr", clone the fork locally, push branches to the contributor's GRASP list, and open PRs back to canonical Archipelago when they want review.
- Forks can have their own maintainer npubs, relays, policies, and release cadence, but the app should clearly label them as forks unless signed by the canonical maintainer set.
The GRASP server policy should enforce this by accepting pushes to maintainer refs only when backed by signed maintainer state, while allowing contributor PR refs from their own npubs.
Repository Layout
Canonical repo announcement:
- repo id:
archy - display name:
Archipelago - clone URLs:
nostr://<maintainer-npub>/<relay-hint>/archyhttps://<grasp-host>/<maintainer-npub>/archy.git
- relays:
- Archipelago-operated relay
- at least two public Nostr relays that support the event load
- GRASP servers:
- Archipelago-operated GRASP instance
- one public GRASP-compatible mirror
Keep the existing HTTP Git remote as a mirror during launch. The docs can
present nostr:// as the preferred contribution path once the workflow is
proven.
UI Requirements
The source app should provide:
- A first-run contribution modal with a real Archipelago source graphic, not a generic text-only dialog.
- Current clone status and local path.
- Branch list, changed files, commit form, and push/open-PR flow.
- PR inbox, issue list, maintainer status, and relay health.
- Explicit identity indicator showing which npub will sign events.
- A merge rights indicator that clearly says contributors can propose changes but cannot merge them.
- A fork flow that creates a user-owned NIP-34 repo announcement and remote, then offers "Open PR to Archipelago" from any fork branch.
- Maintainer badges based only on pinned canonical maintainer npubs, not relay metadata or server-side account names.
- Links to container docs, deployment docs, manifest spec, and open-source readiness tasks.
Backend Work
Add an RPC module for source contribution workflow:
source.repo-info: returns canonical announcement, clone URL, relay set, maintainer npubs, and local clone state.source.ensure-ngit: verifies thengitapp/runtime is installed.source.clone: clones or updates the local source checkout.source.status: returns branch, dirty files, ahead/behind, and PR state.source.commit: creates a local commit from selected files.source.fork: creates a contributor-owned NIP-34 fork announcement and local remote.source.open-pr: pushes a PR branch and publishes a kind1618event.source.update-pr: updates the branch and publishes kind1619.source.issue: publishes a kind1621event.
Backend must shell out through a narrow command wrapper, never arbitrary user
commands. The wrapper should set an isolated working tree under
/var/lib/archipelago/source/archy, run as the Archipelago service user, and
deny operations outside that path.
Security Model
- Never expose maintainer private keys to an Archipelago node.
- Prefer app-specific contributor identities over the node's default identity.
- Require per-action consent for first PR push, issue creation, and signing any event that tags the canonical repository.
- Pin the canonical maintainer npub in the app manifest and backend config.
- Keep the canonical merge-maintainer allow list signed by the
archipelago-maintainerkey; never infer merge rights from GRASP server accounts. - Verify the canonical kind
30617event signature before displaying clone instructions. - Treat GRASP servers as untrusted storage; verify Git refs against signed Nostr state.
- Do not use destructive git operations from the UI without an explicit modal.
- Store local clones and generated patches outside app container writable roots unless the user exports them.
MVP
- Package
ngitas a first-party app. - Stand up one Archipelago-operated GRASP server and one Nostr relay.
- Publish sanitized fresh-history
archythroughngit init. - Add a simple
archipelago-sourceapp that clones source and links out to the preferred Nostr Git browser. - Add app-launcher consent scopes for repository-specific NIP-34 signing.
- Allow issues and PR branch submission from contributor npubs.
- Add a one-click fork flow that publishes a contributor-owned fork announcement referencing canonical Archipelago.
- Keep maintainer merge/status publication manual.
Later
- Native PR review UI with file diffs and inline comments.
- CI status events signed by the build identity.
- FIPS-first source sync between trusted Archipelago nodes.
- Private prerelease repositories using NIP-42 allow lists and/or protected events if the ecosystem support is mature enough.
- Multi-maintainer policy with threshold signatures or explicit maintainer-list rotation events.
Open Questions
- Which maintainer npub should become canonical for
archy? - Should contributor identities be node-default or app-specific by default?
- Which GRASP implementation should be deployed first:
ngit-graspor another NIP-34/GRASP-compatible relay? - Should the source app include a full web Git UI in v1, or launch Gitea/ngit browser links for review while keeping signing/submission native?
- What exact license and contribution certificate should contributors accept before submitting PR events?