Surface the existing pin (keep-from-cull) and per-file delete actions as visible inline buttons on each offline cache row instead of context-menu-only: a star toggles protection from auto-cull (and restore-if-missing), a trash culls that file early. Aligns wording/icons to the star metaphor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6 KiB
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.
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 |
| 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 + pillars/watch-appearance.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.
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 |
docs/glossary.md |
Extended in v2/glossary.md |
docs/roadmap.md |
Supplemented by v2/roadmap.md |
.project/history/20260608_fleet-manager-mesh-design.md |
Download + Net origin |