6.4 KiB
Status & Roadmap
Where the project is and the de-risked path to the full vision. Architecture is in
architecture.md; the mesh design origin is
../.project/history/20260608_fleet-manager-mesh-design.md.
Status at a glance
| Area | Status | Note |
|---|---|---|
| App — playback (VLC / mpv / QuickTime) | ✅ Shipped | blacktv retired → auto-migrated to mpv |
| App — library browser | ✅ Shipped | black index fast-path + NFS walk + registry fallback |
| App — downloads (search + transmission) | ✅ Shipped | via mcp CLI; search needs FlareSolverr |
| App — metadata enrichment + artwork | ✅ Shipped | regex parse + TMDB/IMDb/keyless + ffmpeg frame-grab |
| App — all UI (Home/Player/Library/Search/Downloads/Metadata/Hosts/Logs) | ✅ Shipped | wired, no TODO/FIXME/fatalError debt |
governor (portable-net-tv) |
✅ Shipped (single-host) | watch tracking + prefetch buffer |
mcp (plum-control-mcp) |
✅ Shipped | VLC / black-tv / transmission / display tools |
recommender |
✅ Shipped | enrichment + local recs |
| MLX title refiner | ⚠️ Seam only | TitleRefiner protocol + refiner hook, never assigned |
governor → fleet orchestrator |
❌ Designed | duty assignment / replication floor / zombie reaper not built |
fleet/ (registry, mesh, peers_for/custodians_of) |
❌ Designed | README + spec, zero code |
| Discord planes | ❌ Designed | control/QA/announce + availability bot |
| Multi-identity / cross-fleet | ❌ Designed | single-fleet foundation must land first |
Verdict: the media-client layer is complete and production-grade. The fleet/mesh layer — the project's defining "private tracker made of your friends" — is fully specified and entirely unbuilt.
Repo-state note
The main checkout is mid-reorg: the committed main tree still tracks the old
PlumTV/PlumTVCore sources, while the working tree has the renamed TVAnarchy
sources plus the governor/, mcp/, recommender/, fleet/, and tools/
trees untracked. Committing this reorg is the prerequisite to everything below.
Remaining work — detail
MLX title refiner (parallel, low-risk)
Sources/TVAnarchyCore/Metadata/FilenameParser.swift declares
public protocol TitleRefiner and public static var refiner: (any TitleRefiner)?,
consulted only when regex yields a <2-char title. No type conforms to it and
refiner is never assigned — the pipeline is regex-only. Impact is low (regex
handles the vast majority of SxxEyy releases); this is a deliberate seam, not
debt. Closing it = an MLX-backed refiner for the messy tail.
governor → fleet orchestrator
The spec wants the governor's bandwidth-arbitration brain extended to: run
duty-assignment on registry change, enforce the N-copy replication floor (re-pin
before the last copy vanishes), and run a zombie reaper
(healthy | stalled | dead; recover from mesh first, public re-search fallback).
Today the governor only does single-host watch-follow + prefetch. The
bandwidth/watch foundations are reusable; the orchestration layer is missing. This
is the actuation layer for the fleet/ registry — without it a registry is inert.
fleet/ — the mesh subsystem
fleet/ is README-only. Everything in
data-model.md — registry, duties,
peer-source policy, peers_for/custodians_of — is design-only.
Build order (de-risked; each stage independently shippable)
From the design spec. Each stage ships on its own; later stages depend on earlier.
- Hygiene (prerequisite) — commit the
PlumTV → TVAnarchyrename and the untracked helper subsystems so they are under version control. - Host registry + duty assignment, single fleet (black + apricot + plum + phone). No mesh, no Discord. Unifies what's run by hand today. (Run the governor-generalization track alongside stages 1–3.)
- Seedbox source +
public_swarm_faceduty. Adds an always-on custodian; proves the source model on the zero-risk source first. ("Add a seedbox" is the single most important onboarding step for non-power-users — most multi-device fleets have zero always-on nodes otherwise.) peers_for()over local sources (fleet + seedbox + DHT/public). The user-owned meta-tracker, still single-fleet.- Friend-mesh source + F2F relay. Federates; the custody floor goes cross-fleet. Multi-identity lands here.
- Private-tracker source, default-closed. LAST and highest-consequence:
swarm_isolationforced tof2f_only, un-overridable;contentshare is an account-killer for the source user. Ship only once F2F isolation is battle-tested on safe sources.
Parallel, any time: MLX TitleRefiner (independent, low-risk).
After a working mesh: the Discord planes — control/ops + QA/community +
release announcements (project home server) and content/availability (private mesh
- a bot inside users' own servers, never the public home server). Discord is a surface you notify, not a backbone you route through: custody/reaper/F2F run over WireGuard regardless, and a Discord ban must not take the mesh down.
Non-goals / explicitly deferred (not defects)
BlackTVTargetremoved. Intentional — auto-migrated at runtime toMpvTargetwithCommandsConfig.blackTVDefaults(bin:). Black-TV control still works.- No ratio enforcement. Resolved decision (2026-06-08): ship gift-economy,
build the
custody_capacityknob, leave it off. First lever is visibility, not enforcement; hard ratio is a per-group last resort. Ratio anxiety is the pain being sold against — "minus the ratio police." - No fingerprint-stripping on private shares. Resolved decision: warn hard,
strip never by default. Stripping re-encodes and destroys the quality that
makes a private release valuable; the friend is protected structurally by
f2f_only, the source by the explicit warning. Strip is a per-release opt-in only, never auto. - App doesn't link
governoror call the MCP server directly. By design — it shells out to themcpCLI andrecommenderas subprocesses;governorruns independently under launchd. - Black-TV watch state not on plum. Intentional — black-local, read over SSH, never written across NFS.
- Watch parties (if built) = synchronized local playback; Discord carries only voice + timestamps, never streamed copyrighted video.