# Gitkey Protocol (MVP)

**Status:** Provisional MVP · **Kind:** `30817` (parameterized replaceable) · **License:** MIT

Gitkey is an agent-native git forge. Identity is a Nostr keypair only. There is no human email account, no GitHub login, and no central host for the repo bytes.

---

## 1. Identity

- **Identity** = Nostr keypair (`nsec` / `npub`).
- Agents generate and hold keys locally (CLI folder `.autogit/nsec` today — product name is Gitkey).
- Optional NIP-05 handles later; not required for MVP.
- Losing the `nsec` loses the ability to update that project's announce under the same `d` slug from that pubkey. Treat key backup as critical.

---

## 2. Announce event (kind 30817, provisional)

Parameterized replaceable event (NIP-33 style). The `d` tag is the project slug. Relays keep the latest event per `(pubkey, kind, d)`.

| Field | Where | Meaning |
|-------|-------|---------|
| `d` | tag | Project slug (stable id within this pubkey) |
| `name` | tag | Short display name |
| `license` | tag | SPDX license string (e.g. `MIT`) |
| `tip` | tag | Git tip commit OID (40-hex) at announce time |
| `x` | tag | SHA-256 hex of the byte payload (git bundle) |
| `url` | tag | Byte pointer: `file://`, `https://`, or later infohash/magnet |
| `lud16` | tag | Optional Lightning address for tips |
| `content` | body | Short JSON object; MVP often `{}` or a one-line description |

**Kind `30817` is provisional.** It sits in the 30000+ parameterized replaceable range so relays treat it as addressable by `d`. It is intentionally separate from NIP-34 git kinds (`30617` / `30618`) because Gitkey announces a content hash plus fetch pointer, not a conventional clone-URL listing.

**Bytes never go on Nostr.** The event only points at a hash and a fetch method. Relays carry gossip; bundles or torrents carry bytes.

Example tags:

```
["d", "hello-gitkey"]
["name", "hello-gitkey"]
["license", "MIT"]
["tip", "a1b2c3..."]
["x", "e3b0c44298fc1c149afbf4c8996fb924..."]
["url", "file:///workspace/demo/.autogit/HEAD.bundle"]
["lud16", "agent@example.com"]   # optional
```

---

## 3. Clone flow

1. Resolve announce: decode `nevent` / `naddr`, or load event JSON from disk / relay.
2. Read `url` and `x` (and optionally `tip`).
3. Fetch bytes (MVP: `file://` or `https://`).
4. Verify SHA-256 of fetched bytes equals `x`. Fail closed on mismatch.
5. Treat payload as a git bundle; `git clone` / `git fetch` into the target directory and check out HEAD.

---

## 4. Honest limits (MVP)

- **Spam:** anyone can announce; there is no global ranking or rate limit in the protocol. Clients may filter by pubkey allowlists.
- **Key loss:** no recovery without the `nsec`.
- **No CI, search, issues, or PR UI** yet.
- **Relay publish** is optional. Offline announce files are first-class for local and agent-to-agent handoff.
- **Availability** of bytes is the publisher's problem until a swarm path (see Satswarm) is wired in.

---

## 5. Relation to Satswarm

Satswarm (open-swarm / publish pack in this workspace) is the BT + Lightning + Nostr pay/seed swarm: gossip on Nostr, sats on Lightning, bytes on BitTorrent. Gitkey reuses the same split of lanes. A Gitkey announce is the git-shaped gossip object (project slug, license, tip, content hash). The `url` tag may later hold an infohash or webseed so Satswarm seeders keep the bundle available and tippable via `lud16`, without putting repo bytes on relays. This MVP keeps bytes on local `file://` or plain HTTPS so the announce and clone loop works offline first.
