# Net

**Job:** sync **TVAnarchy data** between installs over BitTorrent transport.

One-liner: *Facts from other TVAnarchy nodes — friends up close, network at distance.*

Net is **not** video bytes (Download). Net is **not** playback (Watch). Net is
the **external face** of [BitTorrentDrive](../packages/bittorrentdrive.md) —
small **editions** (torrent-backed JSONL/SQLite) shared with other installs,
with explicit **trust per part**.

Devices uses the **internal face** of the same package (storage pools, extension
pins within your install). Net and Devices share code; they do not share payloads.

## Scope

| In | Out |
|----|-----|
| Intro markers, grouping, quality prefs | Media file swarms |
| k-anon watch signal aggregates | Raw watchlog export |
| Peer hints for living infohashes | `peers_for` implementation (Download) |
| Edition publish / subscribe / merge | VPN, HTTP bridge, WireGuard setup |

## Trust model

Two modes inside one pillar:

| Trust | Who peers | Example parts |
|-------|-----------|---------------|
| `friends` | `f2f_only` — fleet + 1° friends | `intro-markers`, `grouping`, `quality` |
| `network` | k-anon aggregates, six-degrees signal | `signal`, anonymized `peers-hints` |

Maps to the fleet design's two graphs:

- **Custody graph** → Download (bytes), narrow trust
- **Discovery/signal graph** → Net `network` trust parts

Never conflate **torrent peers** (Download seeders) with **Net peers**
(other TVAnarchy installs).

## Security & Trust Enforcement (v2 spec)
Friends parts always f2f_only + minSources ≥2 before Player trusts (default 1 local only); network = k-anon aggregates only (≥K fleets, default 5 for signal; no per-user rows). Content keys (ContentID + optional fingerprint) **mandatory**; paths forbidden (schema + runtime enforce; provenance fleetId tracked but UI-redacted on friends). Observations from untrusted sources (torrents/obs import) strictly validated vs schema/net/* (additionalProperties:false); generic errors only (no path leakage). Future governor/src/net/ + mcp/src/bridge/net.ts + TVAnarchyCore/Net/ publish/subscribe/merge: mandatory auth on any exposed surfaces; reuse PathGuard for any path-derived (none in Net payloads). Adult scope structurally protected (never raw paths/watchlog; aligns domain priors). Update edition-manifest.json swarmIsolation/mergePolicy + subscription min* on changes. See plan.md App C + correlation/cross-cutting for cross-infra.

## Vocabulary

```
Net
 └── part          dataset type (intro-markers, grouping, …)
      └── edition  versioned snapshot (small torrent)
           └── observation   one fleet's contribution
```

| Term | Meaning |
|------|---------|
| **part** | Named dataset type; fleets subscribe per part |
| **edition** | Immutable-ish snapshot; distributed as a torrent |
| **observation** | Single fleet contribution with confidence + provenance |
| **merge** | Local policy combining observations into the edition view |
| **subscription** | `net/parts/<name>` + `trust` + `edition` pin |

## Parts (planned)

| Part | Trust | Producer | Consumer |
|------|-------|----------|----------|
| `intro-markers` | friends | ffmpeg detect, user skip tap | Watch `PlayerController` |
| `grouping` | friends | manual merge, LLM grouper | Watch `ShowGrouping` |
| `quality` | friends | release preference per show | Download search/add |
| `signal` | network | watch events (k-anon ≥5) | Net discovery, reaper hint |
| `peers-hints` | friends / network | custody awareness | Download `peers_for` |

Content keys use **content identity** (hash / fingerprint), not file paths —
paths leak watch history.

## Transport (external face)

Implemented via **BitTorrentDrive** `ExternalEdition` API — not a separate Net
swarm stack.

- Source kind: `friend_mesh` (peer route inside BitTorrentDrive)
- `swarm_isolation: f2f_only` for `friends` parts always
- `network` parts: aggregated editions only; no per-user rows below k threshold
- Governor `fleet serve` may host edition manifests; bytes ride drive pin layer

See [packages/bittorrentdrive.md](../packages/bittorrentdrive.md).

## Subscriptions (fleet config sketch)

```jsonc
{
  "net": {
    "subscriptions": [
      { "part": "intro-markers", "trust": "friends", "edition": "latest" },
      { "part": "signal",        "trust": "network", "edition": "latest" }
    ]
  }
}
```

Lives alongside `sources[]` in fleet registry — see
[schema/net/subscription.json](./../schema/net/subscription.json).

## Implementation status

| Piece | Status | Location (future) |
|-------|--------|-------------------|
| Pillar spec | **v2 docs** | `v2/pillars/net.md` |
| Schemas | **v2 docs** | `v2/schema/net/` |
| Publish/subscribe runtime | Not built | `net/` or `governor/src/net/` TBD |
| Watch consume intro-markers | Partial local | `PlayerController` skip-intro (settings only) |
| Mesh federation | Designed | stage 4 in `docs/roadmap.md` |

## First slice (recommended)

1. Local intro detect + observation schema (no mesh)
2. Single-fleet edition torrent on the always-on host (dogfood publish)
3. `friend_mesh` subscribe when stage 4 ships
4. Merge + confidence gates before Player uses bounds

## Code today (Net-adjacent, not Net)

These produce **local** data that will become observations:

| Module | Future observation |
|--------|-------------------|
| `PlayerController` skip tap | `intro-markers` |
| `ShowGrouping` / `LocalLLMGrouper` | `grouping` |
| `SettingsStore` skipIntroSeconds | local fallback only |
| `WatchHistory` | feeds `signal` after k-anon merge |

No `NetController` exists yet.