# Cross-cutting Components that serve multiple pillars or are infrastructure beneath them. ## Install identity (internal: fleet) Product term: **Devices** / **install**. One operator identity + registered devices. Not a sixth pillar — **Devices pillar** owns the registry; governor still reads `fleet.json` until rename. | Concern | Watch | Library | Download | Devices | Net | |---------|-------|---------|----------|---------|-----| | Device registry | Playback targets | Scan roots | `mediaRoot`, duties | **Owner** | `installId` on observations | | `fleet.json` | — | — | Governor | Install config | `net.subscriptions[]` | | Mesh join | Gate | — | Transport | **Owner UX** | Editions | Files: `DeviceConfig.swift`, `Mesh/`, `governor/src/fleet/registry.ts`. See [pillars/devices.md](../pillars/devices.md). ## Transport layers (not pillars) | Layer | Used by | Note | |-------|---------|------| | VLC HTTP | Watch | Local control plane | | mpv SSH IPC | Watch | Black control plane | | HTTP bridge `:8787` | Watch, Download (iOS) | Thin client path (being thinned further by the control-plane HTTP daemon on the always-on host) | | WireGuard overlay | Download, Net (designed) | `10.9.0.x` mesh (enables f2f_only for Net friends + Devices re-pin) | | `friend_mesh` torrent swarms | Download bytes, Net editions, Devices re-pin | Peer route in **BitTorrentDrive** | | **BitTorrentDrive** | Net (external) + Devices (internal) | [packages/bittorrentdrive.md](../packages/bittorrentdrive.md) | | SSH rsync | Watch offline cache, Download re-pin | (being replaced by BTD internal for extension tier) | Do not name transport **Net**. Net is the data product on top. ## Infra Security Surfaces (mcp, governor, bridge, ssh, daemons, HTTP, fleet serve, control-plane daemon Phase 7) Cross-cutting infra (MCP subprocess façade, governor 24/7 daemon incl. fleet/* + future net/* tick, bridge HTTP :8787 / stdio, SSH rsync/IPC for blacktv/mpv, fleet serve HTTP peers_for/registry, Phase 7 always-on control-plane daemon) must not default-open. Current: optional bearer (serve.ts 'OFF — open', http TOKEN-empty=true); bake **mandatory** for all new (net/ daemons/bridges/serves). Path inputs: model on mcp bridge/library.ts resolveStreamId (strict realpath + roots + ext guard); extract as reusable PathGuard package for blacktv (direct play-file paths in black-tv.sh), MCP dispatch, Swift (LibraryScanner/MediaPaths prefix checks), future Net/BTD. Least-privilege ssh/sudo (review root for sockets; dedicated users); secrets (FLEET_TOKEN/BRIDGE_TOKEN mgmt, no env leakage). Untrusted data (torrents/obs/editions): strict validate + contentKey + generic errs (contrast current blacktv die "no such path"). No default-open on /health or probes where possible. Update components.md (tag new guards/net infra primary=cross or net), manifest paths, plan App C/checklist. Aligns pillars/net trust model + download peer sources (f2f_only forced). See plan.md phases 7/2/4 + packages faces for ACL separation. ## Theming (cross-cutting chrome, Watch-heavy) See [plan.md Appendix C](../plan.md#appendix-c--best-coding-practices-pillar-separation-dry-switching-and-ui-theming) + [pillars/watch-appearance.md](../pillars/watch-appearance.md) + [pillars/settings.md](../pillars/settings.md) (cross section). - **Not pure SwiftUI legoblocks**: Custom hybrid (SwiftUI views + AppKit NSImage sprites from real .wsz BMPs + text parsers). Exact retro fidelity (nearest-neighbor, 7-seg LED, bevels, spectrum). - **Implementation**: ThemePalette (colors + viz + sidebarSelection) + environment(\.themePalette). WinampSkinLoader/Package/Sprites (core, data only). WinampSkinStore + custom WinampSkin*Views + PlayerView/MiniTransport conditionals on `appTheme.usesWinampChrome`. Fallback WinampComponents (built-in bevel/LED/spectrum). `merging(skin:)` for PLEDIT/VISCOLOR tint. - **Scope**: Whole shell gets palette accents + sidebar tint (optional). Heavy chrome (transport, title bar, spectrum, LED) is Player/Watch only. iOS unaffected. - **Persistence + API**: settings.json cross section (appTheme, winampSkinId/Name). AppLocalAPI + MCP section patches. Bundled base skin in app Resources. - **Extension**: New sheets or built-in themes update ThemePalette + sprite consumers + tests. Always update correlation + v2/plan Appendix C. Future control-plane HTTP daemon on the always-on host thins the Watch control plane but theming (local preference) stays in the native shells. ## Governor split One daemon, multiple pillar jobs: ``` portable-net-tv ├── watch + keeper → Watch history + Download prefetch └── fleet/* → Download retention + peers_for └── (future) net/* → Net edition tick ``` ## MCP / CLI bridge `mcp/` is the subprocess façade the Swift app shells to: - **Watch:** vlc, blacktv, display, media library, bridge stream/remote - **Download:** transmission, search, bridge torrents, bridge fleet Single binary, pillar-tagged domains — see [components.md](./components.md). ## Tools & release | Script | Role | |--------|------| | `build-install.sh` | Dev build → install app | | `tools/release.sh` | Tag + Forgejo release | | `tools/update.sh` | Pull release per platform | | `tools/platform.sh` | OS detection (single source) | | `deploy.sh`, `mcp/deploy/` | Remote deploy helpers | ## External hosts (topology) | Host | Typical pillars | |------|-----------------| | Roaming client (e.g. laptop) | Watch primary, governor, bridge | | Central always-on host | Watch stream target, Download transmission + library root | | Secondary always-on / seedbox | Download custody (designed) | | vps-0 (Iceland) | Download broadcast anchor (designed) | | iPhone | Watch + Download via bridge | ## Docs map | Legacy | v2 lens | |--------|---------| | `docs/architecture.md` | All pillars + two-plane split | | `docs/data-model.md` | State tables → [state.md](./state.md) | | `docs/glossary.md` | Extended in [v2/glossary.md](../glossary.md) | | `docs/roadmap.md` | Supplemented by [v2/roadmap.md](../roadmap.md) | | `.project/history/20260608_fleet-manager-mesh-design.md` | Download + Net origin |