# Bitswarm Protocol Specification (Draft MVP)

**Legal model (normative split):**
1. **Clients MAY seed any content their users choose** (local-only magnets never required to hit a hosted index).
2. **Hosted indexes / this demo site catalog SHOULD filter** via the SPDX allowlist below and MUST NOT ingest arbitrary magnets into the server catalog API.
3. Primary intended *indexed* content: open AI model weights and open datasets, plus tiny demo fixtures.
4. **Copyrighted movies, music, TV, games, warez** are permanently out of scope for **hosted indexes**. Nothing here is legal advice.

Synced with `/workspace/open-swarm-protocol` **v0.2.0**.

---

## 1. Goals

Keep **open** models and datasets alive by combining:

| Layer | Role |
|-------|------|
| **BitTorrent-style bytes** | Piece hashes, infohash-like content id, swarm transfer |
| **Lightning money** | Per-piece payment + retainer (availability) bounties |
| **Nostr gossip / identity** | Listings, seeder ads, bounty notices, (optional) attestations |

Tagline: *Keep open models alive with Lightning — not piracy.*

---

## 2. Roles

| Role | Responsibility |
|------|----------------|
| **Leecher** | Discovers allowlisted listings; pays sats per piece; verifies piece hashes |
| **Seeder** | Advertises availability + rate card; serves pieces after invoice settle; answers retention challenges |
| **Retainer funder** | Opens / funds a daily (or epoch) bounty so seeders stay online even without continuous leechers |
| **Attestor** (optional MVP stub) | Observes challenge results; may publish attestation events. MVP may co-locate attestor with the client |

---

## 3. License allowlist and rejection rules

### Allowlist (SPDX)

- `MIT`
- `Apache-2.0`
- `BSD-2-Clause`
- `BSD-3-Clause`
- `CC0-1.0`
- `CC-BY-4.0`
- `Unlicense`

### Rules (MUST)

1. Every **content listing** MUST include `license_spdx` from the allowlist.
2. **Hosted indexes SHOULD** run a **license gate** before: publishing a listing into the public catalog, registering a seeder ad on the index, opening a retainer on the index, or mediating piece payment through the index.
3. If license is missing, unknown, or not allowlisted → hosted indexes **reject / block**. Do not index.
4. Hosted indexes MUST NEVER include magnets, indexes, or instructions for copyrighted movies/music/TV/games/warez.
5. **Clients MAY** still seed user-chosen magnets locally without uploading them to a hosted catalog.

---

## 4. Content addressing (bytes)

Inspired by BitTorrent, simplified for MVP:

- **Piece size**: fixed per listing (demo fixtures use 256 bytes).
- **Piece hash**: SHA-256 of piece bytes, hex.
- **File hash**: SHA-256 of full payload.
- **Infohash-like id**: `SHA-256( concat(piece_hashes) || content_id || license_spdx )` hex.

Demo listings may use a local `payload_ref` (path under `fixtures/`) instead of a public magnet. Magnets are only appropriate for allowlisted redistributable content; this MVP ships **local fixtures only**.

---

## 5. Event kinds (draft private range)

Kinds **39000–39010** are a **draft / experimental** private range for Bitswarm. Treat as non-final; document names clearly. Prefer parameterized replaceable semantics via `d` tag where noted.

| Kind | Name | Replaceable? | Content (JSON) highlights |
|------|------|--------------|---------------------------|
| **39000** | `content_listing` | parameterized (`d` = infohash) | `infohash`, `file_hash`, `piece_hashes[]`, `piece_size`, `license_spdx`, `payload_ref` or magnet (allowlisted only), `sats_per_mib`, `lnaddress` |
| **39001** | `seeder_ad` | parameterized (`d` = infohash) | `infohash`, rate card (`sats_per_piece` / `sats_per_mib`), `ln_receive`, `challenge_endpoint` stub |
| **39002** | `retainer_bounty` | parameterized (`d` = infohash) | `infohash`, `daily_bounty_sats`, `epoch_hours`, `license_spdx` |
| **39003** | `retainer_fund` | regular | `infohash`, `amount_sats`, `funded_total` |
| **39004** | `challenge_result` | regular | `infohash`, `piece_index`, `expected_hash`, `proof_hash`, `passed`, `payout_sats` |
| **39005** | `attestation` | regular (stub) | Optional third-party confirm of challenge / uptime |

Common tags: `["i", "<infohash>"]`, `["license", "<spdx>"]`, `["d", "<infohash>"]` for parameterized kinds.

MVP transport: **local SQLite Nostr-like store** (required, works offline). Optional best-effort publish to a public relay via WebSocket.

---

## 6. Piece invoice / HTLC memo format

```
infohash|piece_index|piece_hash|nonce
```

Example:

```
a5359f6d…|0|9c1a…|f3a91b02c8d4e7aa
```

- `infohash` — content id  
- `piece_index` — integer  
- `piece_hash` — expected SHA-256 hex of piece  
- `nonce` — payer/seeder anti-replay token  

Whole-file (demo + thick clients):

```
infohash|ALL|remaining_count|file_hash|nonce
```

Alias (accepted by parsers; future hold-invoice binding):

```
infohash|FILE|file_hash|nonce
```

