# v2 roadmap

**See the dedicated [v2/features.md](./features.md) for the comprehensive feature state comparison table (v1 vs v2).**

Phased checklist for the **Watch · Download · Net** pillar model. For the full
migration plan (tasks, PR stack, tests, risks, timelines), see **[plan.md](./plan.md)**.

Phase 0 is documentation only (this `v2/` tree).

## Phase 0 — Pillar model (now)

- [x] Define Watch / Download / Net scopes
- [x] Correlate all components → [correlation/components.md](./correlation/components.md)
- [x] Net JSON schemas → [schema/net/](./schema/net/)
- [x] Machine index → [manifest.json](./manifest.json)
- [x] Link from `docs/README.md` to `v2/`
- [x] Full build plan → [plan.md](./plan.md)
- [x] Watch appearance spec → [pillars/watch-appearance.md](./pillars/watch-appearance.md)

No code moves. No path renames.

## Phase 1 — Net local (single fleet)

Ship Net semantics without federation.

| Task | Pillar | Target |
|------|--------|--------|
| `contentKey` helper unify | Watch | `ContentID.swift` |
| Local observation queue | Net | `~/.local/state/tv-anarchy/net/observations.jsonl` |
| Intro observation on skip | Net | `PlayerController` |
| Merge policy for intro-markers | Net | `v2/net/` or `TVAnarchyCore/Net/` |
| Player reads merged view | Watch | fallback: settings → merged → detect |

## Phase 2 — Net edition publish (dogfood)

| Task | Pillar | Target |
|------|--------|--------|
| Edition builder (jsonl + manifest) | Net | governor or `net/` package |
| Single-fleet edition torrent | Net + Download | always-on host |
| `fleet.json` → `net.subscriptions[]` | Cross-cutting | extend data model |

## Phase 3 — Net subscribe (friend_mesh)

Requires Download stage 4 (F2F relay).

| Task | Pillar | Target |
|------|--------|--------|
| Subscribe + verify editions | Net | `friend_mesh` source |
| k-anon merge for `signal` part | Net | network trust |
| Governor `net/` tick alongside fleet daemon | Net | `governor/src/net/` |

## Phase 1b — Library titles + display names (parallel, largely shipped)

| Task | Target | Status |
|------|--------|--------|
| Title Library spec | [pillars/library-titles.md](./pillars/library-titles.md) | ✅ + shipped impl |
| Display spec | [pillars/library-display.md](./pillars/library-display.md) | ✅ + shipped impl |
| `TitleLibrary` store | `~/.local/state/tv-anarchy/titles/` by `contentKey` | Shipped (TitleLibrary.swift + Store) |
| Lookup before MLX | Database hit → skip model | Shipped (DisplayNames + refiner gate) |
| `episode_refiner.py` + LocalLLMEpisodeRefiner | M2 MLX, episode-aware, write library row | Shipped + wired |
| TVmaze/TMDB ep ingest | One-shot → library, not per-browse | Remaining (Phase 1b polish) |
| `LibraryDisplayNames` + scanner | Denorm into `library.json` | Shipped (scanner calls resolve; tolerant CachedEpisode) |
| Player / queue / iOS / bridge / MCP | Read `displayName` only | Partial (core paths updated; dual-scanner TS mcp + full consumer migration remaining) |
| Goldens + settings (library section) + legacy migration + dual-scanner parity | Per library-display.md | Remaining (see plan.md Appendix C) |

**Exit:** Known episodes never re-hit MLX or APIs; no raw filenames in UI for indexed catalog episodes. Reconcile v2/manifest.json + plan.md + correlation/ on any further work. See plan.md §5 refined phases + Appendix C.

## Phase 6b — Settings per pillar (parallel)

| Task | Target |
|------|--------|
| Spec | [pillars/settings.md](./pillars/settings.md) ✅ |
| Nested settings decode | `SettingsStore` |
| SetupView sections | Watch · Library · Download · Net · Devices · General |

## Phase 6c — Devices shared media volume

| Task | Target |
|------|--------|
| Spec | [pillars/devices-storage.md](./pillars/devices-storage.md) ✅ |
| Storage pool config | `devices.json` or `storage-pools.json` |
| Placement index | `media-placement.json` |
| Extension warmup (alias) | Replace duplicate offline-cache rsync |
| UI | Spare folder + quota on This Mac / Devices |

Use case: client machine spare space extends the central storage; watch on client → smart copy to extension tier on the client
extension tier; warmup aliases extension path.

## Phase 6d — Library + Devices pillar split (doc)

| Task | Status |
|------|--------|
| [library.md](./pillars/library.md) | ✅ |
| [devices.md](./pillars/devices.md) | ✅ |
| Correlation + manifest | ✅ |
| UI copy fleet → install | ✅ Done (string sweep) | DevicesView, IntroView, DeviceEdit, plists, glossaries + DeviceConfig comments. Internal names/CLI/fleet.json still fleet-engine. |

## Phase 6a — Watch appearance (parallel, macOS)

Shipped base: built-in Winamp themes + `.wsz` import on Player. See
[pillars/watch-appearance.md](./pillars/watch-appearance.md).

| Task | Pillar | Target |
|------|--------|--------|
| Doc + v2 correlation | Watch | `v2/pillars/watch-appearance.md` ✅ |
| `PLAYPAUS` status LED | Watch | `PlayerView` |
| MiniTransport skin sprites | Watch | `MiniTransport.swift` |
| `AppLocalAPI` skin fields | Watch | settings patch |
| Import validation preview | Watch | `SetupView` |

Does not block Net phases 1–3.

## Phase 4 — Docs & UI alignment (optional)

| Task | Notes |
|------|-------|
| Settings → Net subscriptions | Toggle parts |
| Sidebar grouping labels | Watch / Download / Net sections |
| Migrate `docs/architecture.md` lead with pillar diagram | Keep ops detail in place |

## Phase 5 — Universal client (north star)

Unchanged from [`docs/roadmap.md`](../docs/roadmap.md): the control-plane HTTP daemon on the always-on host thins Watch;
pillars remain valid — Net and Download live server-side, Watch becomes thin HTTP.

## What not to do in v2

- Rename `TVAnarchyCore` → three frameworks (premature)
- Move `governor/` under `v2/` (operational path stays stable)
- Call VPN/bridge/mesh transport "Net"
- Use path-based Net keys
- New infra/daemons/bridges/serves/HTTP/MCP without mandatory auth + PathGuard + generic errs + least-priv (per plan.md expanded checklist 6-7 + App C infra security + pillars/net.md). Default-open (like current bridge/serve) or ad-hoc paths forbidden. Update correlation/manifest/checklist + plan App C same PR.

## Success criteria

| Milestone | Signal |
|-----------|--------|
| Phase 0 | Operator can answer "which pillar?" for any file via `v2/` |
| Phase 1 | Skip intro uses merged local intro-markers |
| Phase 2 | Another device can pull edition torrent from the always-on host |
| Phase 3 | Friend fleet contributes observation; merge updates skip window |
| Phase 8 | Discord bridge posts availability/control events to separated planes (contentKey only); mesh unaffected by Discord state |