← The specification

What the glue is doing

Rendered from spec at76d46f3 (2026-10-25) · its source · Edit this page

Status: Accepted · Audience: Both · Area: N — Companion


Purpose

Area H is the automation people bolt onto a media stack by hand — cross-seeding, announce-driven grabbing, quality-profile sync, library cleanup, playback statistics — and K1 is the metrics pipeline beside it. Five of the six share one rule: they prove the wiring rather than trusting it, and a configuration that has not proven itself is unproven, never ready. Cleanup has a gate in its place — a dry run, then a confirmation.

That rule is the one a small screen loses first. An automation that is running looks, from a phone, exactly like one that is working, and every one of these fails by looking fine. So what this page asks of the app is mostly the same thing each time: show the proof, keep unproven apart from ready, and offer the acts each feature makes reachable without a terminal.

Queue self-healing (H5) is not here: N16 already shows what it would do and did (N16-R8 to N16-R11), and keeps its acts off the app (N16-R12).

Behaviour

Unproven is its own answer, everywhere on this page

Five of these end their wiring with a proof against real data — a match for a real local item, a real announce line through a test filter, a read-back of the scores that were written, a known recent play queried back, a series present in the store. Where the proof has not held, the feature is unproven, and the app shows that as its own state. Running is never shown in its place.

Cross-seeding: a match is the data, not the name

A candidate is a match only when the files, sizes and pieces agree (H1). A near-miss — an extra folder, a stray small file — is a near-miss, and a partial match is partial with its missing pieces named. Neither is added as a seed, and neither is counted as one here. An indexer that failed during a pass is named as failed for that pass while the others go on; a client credential that failed its proof halts additions, and the app says additions are halted rather than that nothing was found.

The operator can start a search, list what it matched and run the proof from here.

Announce-driven grabbing: a quiet channel and a dead one are different

Each announce channel has a connection state and an idle time (H2). A disconnected watcher looks like a quiet night until a missed release proves otherwise, so the app shows both, per channel, and never shows a disconnected channel as watching.

A filter that has matched nothing over its window is a dead rule until shown otherwise. A filter at its grab cap is holding, not failing. A match whose destination was unreachable is held, not dropped. Each is shown as itself. The operator can reload filters, replay an announce line through them, and run the proof from here.

Quality-profile sync: the preview is the decision, and the read-back is the result

A sync is previewed before it is applied — every create, update and, where pruning is on, every removal, with the score it changes (H3). The app shows the preview and applies only the plan that was previewed. Afterwards, success is what the read-back confirmed, instance by instance: a write the service accepted and the read-back did not find is a failure, and another tool rewriting the same instance is a conflict, not a reason to apply again.

Library cleanup: the evidence travels with the candidate

A cleanup candidate is chosen from what the household watched and asked for, and carries the rule that chose it, the room it gives back and the evidence behind it (H6). The app shows all three with each candidate, and shows only the evidence the stack gave: a child’s viewing is not evidence the stack gives, and the app has no other source. A series is shown as its members, each with its own evidence, never as one row to delete. A confirmation covers the plan it was given; where the stack re-presents a plan because the candidates changed, it is a new plan asking for a new confirmation.

N12 already forbids the app proposing a set, pre-selecting, or acting on a threshold (N12-R4, N12-R9).

Playback statistics: whose, and how sure

What was watched, by whom and how far through is the household’s most personal record (H8). Whose statistics a person may see is the core’s answer for the identity signed in, and the app holds no rule of its own about it (N3-R2). A device that reports no progress gives unknown, not watched and not unwatched. Somebody with no recorded playback is said to have none rather than shown an empty chart, and a history that begins where backfill could not reach says where it begins (N11-R1).

What somebody watched is never in a notification and never drawn behind the lock.

Metrics: the pipeline’s proof is shown here; the dashboards are not

The metrics pipeline proves three things: each target is up in the collector, each service’s series are present in the store, and each curated dashboard’s panels resolve against real data (K1). The app shows each, per target and per dashboard, with the remedy for each failure. A running exporter is not a healthy target, a service with no exporter is unmonitored rather than covered, and a collector scraping without retaining is not a healthy pipeline. The retention bound and the projected growth of the store are shown. Regenerating targets and dashboards, and running the proof, are offered from here.

The dashboards themselves are not drawn in the app. They are a bundled renderer’s own screens, generated as files from the stack’s definition (K1-R4), and lemonfiber’s other surfaces do not draw them either. Drawing them here would mean the app holding a second copy of every provisioned query, which drifts from the first the day a dashboard is regenerated, and the app renders the core’s answers rather than keeping copies of its own (N1-R1). Where the stack gives the renderer’s address, the app offers it as that address; it never builds one.

States

State Meaning
Unproven Wired, and the proof has not held. Never shown as ready or running.
Ready The proof held against real data.
Holding A cap or an unreachable destination is holding matches. Not failing.
Near-miss A cross-seed candidate that differs in layout. Not a match.
Previewed A sync or cleanup plan shown. Nothing applied.
Conflict Another tool wrote the same instance. Not re-applied.
Unmonitored A service with no exporter. Not covered.
Unknown The state could not be read. Never shown as ready.

Edge cases

  • A cross-seed pass where one indexer drops mid-way. That indexer is failed for the pass; the matches the others found stand.
  • A filter authored to match everything. Still capped; the cap is shown holding rather than the filter shown as healthy.
  • A catalogue source unreachable during a sync. Nothing was applied, and the instance is shown untouched rather than partly synced.
  • A cleanup item removed by hand before the plan ran. Already gone, not a failed deletion.
  • A member with no recorded playback. Said, not charted as zero.
  • A target inside the VPN namespace. Its state is the collector’s, across the path it is scraped on; it is not shown down for being inside the tunnel.

Requirements

ID Requirement
N26-R1 Where one of these features reports a proof that has not held, the app MUST show it as unproven, and MUST NOT show it as ready or as running (H1-R8, H2-R6, H3-R5, H8-R2, K1-R14).
N26-R2 The app MUST offer starting a cross-seed search, listing its matches and running its wiring proof (H1-R14).
N26-R3 A cross-seed near-miss and a partial match MUST each be shown as such, the partial one with its missing pieces, and neither MUST be counted as a match (H1-R9, H1-R10).
N26-R4 An indexer that failed during a pass MUST be named as failed for that pass, and a failed client credential MUST be shown as halting additions (H1-R11, H1-R13).
N26-R5 Each announce channel MUST be shown with its connection state and idle time, and a disconnected channel MUST NOT be shown as watching (H2-R9).
N26-R6 A filter that has matched nothing over its window, a filter holding at its cap, and a match held for an unreachable destination MUST each be shown as itself, and MUST NOT be flattened into healthy or failed (H2-R7, H2-R11, H2-R13).
N26-R7 The app MUST offer reloading filters, replaying an announce line through them, and running the wiring proof (H2-R14).
N26-R8 The app MUST offer previewing a quality-profile sync, showing every create, update and removal with its score change, and MUST offer applying only the plan that was previewed (H3-R3, H3-R7, H3-R14).
N26-R9 A sync MUST be shown as succeeded, instance by instance, only where the read-back confirmed it, and a conflict with another tool MUST be shown as a conflict (H3-R4, H3-R10, H3-R11).
N26-R10 A cleanup candidate MUST be shown with the rule that selected it, the space it reclaims and the evidence the stack gave, and the app MUST NOT show evidence from any other source (H6-R2, H6-R9).
N26-R11 A series or collection MUST be shown as its members, each with its evidence, and an item already removed by other means MUST be shown as already gone rather than as a failed deletion (H6-R12, H6-R13).
N26-R12 A confirmation MUST cover only the cleanup plan it was given; a plan the stack re-presents MUST be confirmed afresh, and a run with no candidates MUST be said to have none (H6-R3, H6-R11, H6-R15).
N26-R13 Whose playback statistics are shown MUST be the core’s answer for the identity signed in, and the app MUST NOT hold a rule of its own about it (H8-R4, N3-R2).
N26-R14 Completion a device did not report MUST be shown as unknown, a person with no recorded playback MUST be said to have none, and where backfill is unavailable the app MUST say where the history begins (H8-R3, H8-R8, H8-R13, N11-R1).
N26-R15 What somebody watched MUST NOT appear in a notification or in anything drawn while the app is locked (H8-R5, N4-R10, N4-R24).
N26-R16 The metrics pipeline MUST be shown per target and per dashboard as up, series present and rendering, each failure with its remedy; a service with no exporter MUST be shown as unmonitored, and a collector that scrapes without retaining MUST NOT be shown as healthy (K1-R5, K1-R6, K1-R7, K1-R11, K1-R12).
N26-R17 The metrics store’s retention bound and projected growth MUST be shown (K1-R9).
N26-R18 The app MUST offer regenerating scrape targets and dashboards, and running the pipeline proof (K1-R13).
N26-R19 The app MUST NOT draw the metrics dashboards or their series, and MUST say that they are the renderer’s own screens; it MUST offer the renderer’s address only where the stack gives one, and MUST NOT construct one. Drawing them would hold a second copy of every provisioned query (K1-R4), and the app renders the core’s answers rather than copies of them (N1-R1).

Notes

The contract carries none of this. Every feature on this page is planned, and no envelope the stack publishes is about any of them: nothing names a cross-seed match, an announce channel, a profile sync, a cleanup candidate, a playback or a metric. Every row here waits on the contract, and N1-R17 stops the work until it carries what the row needs. Nearby envelopes are not substitutes:

Feature Nearest envelope Why it does not answer
H1 stop-seeding One torrent’s standing and ratio. Nothing about matches, near-misses or the proof
H2 — Nothing
H3 quality: customised, overwritten The preset’s configuration and whether it was hand-edited. No diff of custom formats or scores, no read-back
H6 space Candidates for reclaiming room by standing. Not chosen from watch data, and no rule or evidence
H8 history The record of changes to the stack, not of playback
K1 dashboard.telemetry Whether the dashboard screen is current. Not a metric, a target or a series

N26-R19 is the one exclusion on this page, and it is written as one because parity is otherwise the rule (N1-R2). The pipeline’s proof is offered here in full; the dashboards are a bundled service’s own screens, which no lemonfiber surface draws.

  • N1 — parity, and rendering the core’s answers
  • N12 — removal, and what the app may not propose
  • N16 — queue self-healing
  • N11 — a record’s horizon
  • N3 — what a member sees
  • N4 — notifications and the lock
  • N24 — choosing a quality preset
  • H1, H2, H3, H6, H8 — the glue
  • K1 — metrics and dashboards