Articulate. Home Famflix Ops (Airtable) Famflix v100
Project blueprint · v100 · clean start · 28 Jun 2026

Famflix — v100

A private streaming service serving popular & new TV and movies to ~30 friends. This is the clean-start blueprint — it supersedes and deprecates v4. MediaServer / StudioServer as a sprawling code-pile is retired; this is the spec everything gets rebuilt against.

This is a blueprint, not a live status page. It deliberately holds no live numbers (that's the v4 mistake — a static page can't carry real-time data honestly). Live ops live in Airtable; the consumer face is famflix.app.

1 · Goal & principle

The goal: friends and family (up to ~30) open Famflix and find the popular and new TV and movies they actually want to watch — and it stays clean, current, and effortless to run.

The principle — subtraction

70 moving parts to do a 6-part job.

The old system failed from sprawl, not missing features: 14 rogue scrapers, 6 acquisition containers, music grabbers, 11 overlapping monitors, ~60 ad-hoc scripts — all bypassing each other, no gate, no taste, vanity metrics. v100 is the boring, robust, known shape and nothing else.

2 · The 6-service stack

The entire system is six services. Acquisition has exactly one road: request → approve → search → download → Plex. No scrapers, no second path.

LayerServiceJob
StreamPlexLibrary + the 30 friend accounts (native Plex sharing)
Front doorOverseerrFriends browse popular & new (TMDB built-in) and request
Fulfil — filmRadarrTurn an approved movie request into a download
Fulfil — TVSonarrSame, for series/episodes
FindProwlarrOne indexer hub feeding Radarr + Sonarr
DownloadTransmissionThe only download client

Declared in one compose file, not 70 launchd plists. If it's not one of these six, it doesn't run.

3 · Curation model — acquire from the gap

Content enters only two ways, both deliberate:

  1. Friend requests — via Overseerr, with your approval as the gate. Overseerr's Discover surfaces TMDB trending / popular / upcoming, so "popular & new" is native.
  2. Curated auto-lists — 2–3 lists (e.g. "Popular Movies this month", "Trending TV") feed Radarr/Sonarr automatically, with a hard genre block on Reality / Soap / Game-Show, so the library stays fresh without anyone lifting a finger and the reality-TV war is over by design.
Proven pattern — your own LocalSpotify. It already does this for music: rank by real listening (lifetime + recent plays), diff against the library, acquire only the gap. v100 applies the same idea to TV/film — acquire from the gap between demand (popularity / requests) and what's already on the shelf. Acquire from the gap, never from a scraper.

4 · Why this ends every failure we hit

Old failurev100 fix
Reality TV kept returningNo scraper exists; entry only via request or genre-filtered list
Dupes / junk / wrong qualityOne quality profile in Radarr/Sonarr; no parallel grabbers
Vanity counts (4,209 junk albums)Measure against demand + watch, not raw totals
TR sat empty when you checkedRequests + auto-lists keep a real queue; one path, observable
No gate — things acted on stale stateOverseerr approve = native gate; Airtable = audit/oversight
70 processes, nobody knew what ran6 services, one compose file, one dashboard

5 · Build phases

#PhaseWhat
0DemolitionArchive the ~60 old scripts + parked plists + dead container configs. Keep only Plex DB + library + DAS. Rename project MediaServer/StudioServer → Famflix. mostly done
1Clean coreRebuild the 6 services from one compose file; one quality profile set once
2Curation rulesGenre block + 2–3 curated popular/new lists; open Overseerr to the 30 friends, approval on
3Storage hygieneClear PERSONAL (slskd junk) + purge reality strays; add retention (expire unwatched)
4One dashboardSingle status page + ntfy on failure only — not 11 monitors
5This pagev100 blueprint published as source-of-truth; v4 deprecated done

6 · Done so far — the teardown

Today's session already executed most of Phase 0:

So the box is already most of the way to the v100 baseline: the mess is off, the core (Plex) is intact, and the rebuild starts from a clean floor.

7 · Storage & drive roles

Policy: PERSONAL holds zero media. All media — movies, TV, music — lives on MEDIA; PERSONAL is personal data only (backups, home-video, iCloud, TimeMachine). The 2 TB SSD is downloads/transcode and is kept free. A 20 TB drive is planned to absorb the ~2 TB music library (and 4K films) that MEDIA can't currently hold.

DriveSizeUsedFreeRole
MEDIA — Seagate 8 TB8.0 TB79%1.73 TBprimary media library (movies + TV; music when 20 TB lands)
MEDIA-MIRROR — WD 8 TB8.0 TB72%2.27 TBnightly backup of MEDIA
PERSONAL — Seagate 4 TB4.0 TB77%0.93 TBpersonal data only — being cleared of all media
2 TB — Crucial SSD2.0 TB13%1.76 TBdownloads + transcode + docker configs (kept free)
System — internal494 GB6%288 GBmacOS + Plex DB
This session: PERSONAL recovered 93% → 77% (~700 GB) — deleted duplicate music (folder + within-album), reality/talk TV, and redundant non-4K movie copies (4K kept per the 20 TB plan). Still on PERSONAL: ~2.1 TB music library + ~58 GB misplaced video to move to MEDIA, and ~230 GB slskd dupes/junk to delete. Full clear to 0 media completes when the 20 TB drive is installed — MEDIA (1.73 TB free) can't hold the 2.1 TB music bulk today. Measured live via SSH to Studio, 28 Jun.

8 · Capabilities — StudioServer

Every API, key, tool, and infrastructure item used by this project. Secret values are NOT here — they live in the vault at Claude/credentials.md. Scoped to Famflix / StudioServer only.

Hardware

ItemDetail
Mac Studio M4 Max36 GB · macOS · 192.168.1.246 · Tailnet 100.82.41.69 · ssh anthonybooth
Thunderbolt DASMEDIA 8 TB (Seagate IronWolf) · MEDIA-MIRROR 8 TB (WD Red Plus) · PERSONAL 4 TB (Seagate IronWolf)
Crucial X9 Pro 2 TB SSD (USB)Downloads + docker configs · kept free

Native services (launchd)

ServicePortRole
Plex32400Library + streaming + 30-account sharing
Transmission9091Torrent client · peer port 51420 gateway-forwarded

Containers (OrbStack · ~/famflix/docker-compose.yml)

ContainerPortRole
radarr7878Movie fulfil
sonarr8989TV fulfil
prowlarr9696Indexer hub (1337x · YTS · TPB · Knaben · EZTV · TorrentGalaxy)
overseerr5055Friend request front-door
flaresolverr8191Cloudflare bypass for indexers
ntfy8090Self-hosted push notifications
open-webui3000Local LLM UI (Ollama)
glances61208System monitor
kometaPlex collection manager (scheduled, not always-on)

Retired / not running

ItemStatus
lidarrIntentionally dropped in v100 — music acquisition retired
slskdInstalled at ~/slskd/ · launchd plist retired · not running

APIs & external services

ServiceUse
TMDBMovie/TV metadata · popular/trending feeds · imdb_id passthrough
TraktRadarr/Sonarr import lists · OAuth auto-refresh
Backblaze B2Bucket Media-Famflix · us-east-005 · rclone mirror of PERSONAL
ntfy (self-hosted)iOS push via Studio port 8090 → ntfy.sh upstream relay

Networking & access

LayerDetail
Cloudflare tunnel 048adfa7famflix.app · request.famflix.app · dashboard.articulate-ai.work
TailscaleSandbox SSH chain → Studio · ephemeral node via run-on-macpro.sh
Etisalat FGA228BETI192.168.1.1 · conntrack ceiling applies · port 51420 forwarded

Monitoring scripts (launchd on Studio)

ScriptCadenceJob
collect.py5 minHealth JSON → dashboard.articulate-ai.work
studio-sampler60 sStability samples
scotty-hourly1 hrPASS/FAIL + ntfy alert
goal-watcher.py6 hrLibrary progress + ETA
storage-audit.pyDaily 05:00Drive usage report
media-mirror.shNightly 00:00rsync MEDIA → MEDIA-MIRROR

Operational surfaces

SurfaceURLUse
Airtable — StudioServer Ops baseappdpP3oFFAs2qzGVTV Cleanup · Acquisitions · launchd audit
Live dashboarddashboard.articulate-ai.work5-min health · storage · container status
This pagestudioserver.vercel.appBlueprint · static · source of truth
Consumer facefamflix.appFriend-facing Overseerr
Famflix · v100 blueprint · 28 Jun 2026 · supersedes v4 · the spec the rebuild is measured against. Ops: Airtable · Consumer: famflix.app