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.7 KiB
BitTorrentDrive (shared package)
Job: Move and pin bytes between machines using the same torrent-style swarm stack — one engine, two product faces.
One-liner: Internal device storage glue + external install federation transport.
Not a pillar. Net and Devices are consumers with different policies and payloads. Download pillar also uses the stack for media acquisition (public swarms) but owns search/custody/reaper product logic separately.
Two faces, one package
flowchart TB
subgraph btd [BitTorrentDrive package]
Swarm[Swarm session + piece store]
Pin[Pin / unpin / verify]
Route[Peer route: LAN · mesh · f2f]
Manifest[Manifest + contentKey index]
end
subgraph devices [Devices pillar — internal]
Pool[Storage pools + tiers]
Place[Placement index]
Warm[Extended warmup]
Repin[Re-pin within install]
end
subgraph net [Net pillar — external]
Ed[Edition torrents]
Sub[Subscribe + verify]
Pub[Publish observations]
end
subgraph dl [Download pillar — media product]
Custody[custody floor policy]
Trans[Transmission add]
end
Pool --> Pin
Place --> Manifest
Warm --> Pin
Repin --> Pin
Ed --> Swarm
Sub --> Swarm
Pub --> Ed
Custody --> Repin
Trans --> Swarm
| Face | Pillar | Audience | Payload | Trust |
|---|---|---|---|---|
| Internal | Devices | Machines in your install | Media files, extension tier copies | Install-scoped; device registry |
| External | Net | Other installs (friends / network) | Small editions (JSONL, manifests) | Per-part friends / network |
| Acquisition | Download | Public / trackers | Release media swarms | DHT, private tracker, seedbox |
Internal and external share: piece verification, pin lifecycle, peer routing over
friend_mesh / LAN, manifest hashing. They differ in namespace, ACL, and
size policy.
Internal face (Devices)
Used for devices-storage.md:
| Operation | Example |
|---|---|
| Promote | Watching on dev Mac → pin next episodes to extension tier |
| Alias resolve | Catalog path → nearest local piece location |
| Pool sync | Spare capacity on a client registered as extension of the central volume |
| Re-pin | Governor moves canonical copy between storage devices (same install) |
| Verify | Hash check after rsync-equivalent fetch |
Transport preference: LAN → install mesh → never public DHT for internal media pins.
// Internal pin record (sketch)
{
"contentKey": "…",
"logicalPath": "tv/Show/S01E01.mkv",
"tier": "extension",
"deviceId": "laptop1",
"pinState": "complete",
"source": { "face": "internal", "fromDeviceId": "central" }
}
External face (Net)
Used for net.md:
| Operation | Example |
|---|---|
| Publish edition | intro-markers-v12.jsonl + manifest → small torrent |
| Subscribe | Pull friend install's edition; verify sha256 |
| Re-merge | Import observations into local Net store |
Transport: friend_mesh with swarm_isolation: f2f_only for friends
parts; k-anon aggregates only for network parts (no raw rows in swarm).
// External edition manifest (see v2/schema/net/)
{
"part": "intro-markers",
"edition": "2026-06-21",
"trust": "friends",
"sha256": "…",
"infohash": "…"
}
Net never pins multi-GB video through this face — only edition blobs.
Package boundary (API sketch)
BitTorrentDrive/
├── Session // one swarm router per process
├── InternalPin // Devices: media piece pins
├── ExternalEdition // Net: small edition pins
├── Manifest // contentKey ↔ locations
├── PeerRoute // LAN / wg / f2f source union
└── Verify // piece hash, manifest sha256
| Method | Face | Caller |
|---|---|---|
pinInternal(contentKey, targetDevice, tier) |
internal | PlacementController |
resolveNearest(contentKey, deviceId) |
internal | MediaPaths |
publishEdition(part, blob) |
external | EditionPublisher |
subscribeEdition(manifest) |
external | EditionSubscriber |
unpin(ref) |
both | cull, reaper, pool quota |
Swift owns resolveNearest (Player latency). Governor/daemon owns pin sync tick and edition subscribe (24/7).
Planned locations
| Layer | Path (recommended) |
|---|---|
| Swift read path | Sources/TVAnarchyCore/BitTorrentDrive/ |
| Daemon actuation | governor/src/drive/ or governor/src/btdrive/ |
| Types shared with fleet | extend governor/src/fleet/types.ts SourceKind |
| Net publisher | governor/src/net/publish.ts → calls ExternalEdition |
| Devices placement | PlacementController → calls InternalPin |
Do not duplicate swarm logic in Net and Devices modules — both call BitTorrentDrive.
Relationship to Download
| Concern | Owner |
|---|---|
| Search, add magnet, transmission UI | Download pillar |
Custody floor, reaper, peers_for policy |
Download pillar |
| Moving bytes after policy says so | BitTorrentDrive (internal face) |
| Public swarm leeching | Transmission + Download; may share piece store later |
friend_mesh in peers.ts is the peer route BitTorrentDrive uses for both
internal re-pin and external edition fetch.
Settings
| Pillar | BitTorrentDrive-related settings |
|---|---|
| Devices | Storage pools, extension quota, per-device offline policy |
| Net | Subscriptions, contribute, trust per part |
| Download | Bandwidth, custody floor (fleet.json) |
| cross | — |
Phases
| Phase | Face | Deliverable |
|---|---|---|
| 1 | internal | Placement index + pinInternal MVP (extension warmup) |
| 2 | external | Edition publish/subscribe on the always-on host |
| 3 | both | Unified PeerRoute in governor daemon tick |
| 4 | internal | Re-pin actuation via drive, not ad-hoc rsync |
Tests
| Test | Face |
|---|---|
InternalPinTests |
promote, resolve, quota eviction |
ExternalEditionTests |
manifest verify, subscribe idempotent |
PeerRouteTests |
LAN before mesh; f2f isolation |
Glossary
| Term | Meaning |
|---|---|
| BitTorrentDrive | Shared package; not a pillar |
| internal face | Devices — within install |
| external face | Net — across installs |
| pin | Retain verified pieces for a contentKey at a location |
| edition | External-face manifest + small blob swarm |