← The specification

Feature catalogue

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

Status: Accepted

v1 is the seven product areas (A–G) — the contract the technical spec is written against, where every architecture and implementation decision must trace to a feature requirement here, not the other way round. The ecosystem adds four areas (H–K) plus F3, catalogued below the v1 areas and sequenced before 1.0.0 on the same train. Area L — Release & distribution spans both, and carries one release: L1 ships 1.0.0, which is the scoped work of getting there rather than a summary of it. The generated feature board lists every feature with how far it is built and the version it ships in; index.json is the same board for tools: the counts, the version train, and the board.json in each area’s directory that lists its features.

Every feature carries two answers that are easy to confuse and are kept apart. status is about the specification — draft until it is agreed, then accepted, and citable. maturity is about the implementation — planned, building, built, shipped (with the version that carried it), or withdrawn. It is derived rather than written: scripts/maturity.py reads every repository’s tracker and every version manifest, and the maturity workflow opens the pull request that rewrites it whenever the trackers move a feature (OPS-R78). withdrawn alone is set by hand. A feature is routinely accepted and planned for a year; conflating the two would lose whichever question is asked less often.

built and shipped are also worth keeping apart. A feature whose every requirement is met sits in built until the version carrying it is released — which is a different fact from being half-written, and building used to have to mean both. It is the state OPS-R54 can actually gate on: shipped means out in a released version, so demanding it before a release is a gate nothing could ever pass.

A requirement added to a built or shipped feature reopens it: it is building again until the implementation tracker ticks every requirement it defines, and status_lint.py refuses a catalogue that says otherwise (OPS-R73).

How to read a feature doc

Each follows the same shape:

Section Contains
Purpose What problem it solves, for whom. One paragraph.
Behaviour What the user sees and does. Functional only — no crates, no env vars, no module names.
States The states it can be in and what moves between them.
Edge cases What happens when it goes wrong. Usually the longest section, deliberately.
Acceptance criteria Numbered, testable, RFC 2119. A1-R1, A1-R2, …

Requirement IDs

Requirements live inside their feature — there is no separate requirements tree. An ID is <feature>-R<n>: A1-R3 is the third acceptance criterion of feature A1.

IDs are permanent. A requirement that’s removed is marked Withdrawn in place; its number is never reused. Tests and commits cite these IDs.

Audiences

Two, and they need naming because most features serve only one:

Audience Who What they touch
Operator The person who sets it up and keeps it running lemonfiber (CLI/TUI/web), occasionally a service admin UI
Household Everyone else in the home Seerr to request, Jellyfin to watch. Never lemonfiber.

A household member has exactly one account — their Jellyfin login, which Seerr authenticates against. The multi-account problem is an operator problem only.


A — Getting started

The hardest part of the product, and where most users are lost today.

ID Feature Audience
A1 Prerequisites & account guidance Operator
A2 Setup wizard Operator
A3 Credential validation Operator
A4 Reconfiguration Operator
A5 Migration from an existing stack Operator
A6 Clean uninstall Operator
A7 Credential management & rotation Operator

B — Running it

ID Feature Audience
B1 Forms & partial stacks Operator
B2 Lifecycle control Operator
B3 Live dashboard Operator
B4 Log viewing Operator
B5 Notifications & alerting Both
B6 Controlling a stack on another machine Operator
B8 Autostart & boot persistence Operator
B9 Open notification back-ends Both
B10 Hosting long-running commands Operator

B7 (remote access for the household) is deferred — household features are LAN-only until it lands. It returns as I1 in 0.22.0, once a self-hosted overlay control plane (Headscale + self-hosted relay) makes it possible without the proprietary control plane that blocked it (Tailscale). See ADR-0010 for the related runtime decision and the roadmap.

C — Trust & correctness

Features that exist because P3 demands the tool prove things rather than assume them.

ID Feature Audience
C1 Diagnostics (doctor) Operator
C2 VPN verification Operator
C3 Auto-remediation Operator
C4 Support bundle Operator
C5 Storage & hardlink management Operator
C6 Web UI security & binding policy Operator
C7 Queue health & stuck items Operator
C8 Provider health & quota tracking Operator
C9 Config drift detection & seed policy Operator

D — Content & household

ID Feature Audience
D1 Service auto-wiring Operator
D2 Quality presets in plain language Operator
D3 First-content walkthrough Operator
D4 Household request flow Household
D5 Disk space management Operator
D6 Household identity & invitations Both
D7 Request approval & quotas Both
D8 Parental controls Both
D9 “Where is my show?” pipeline trace Both
D10 Bandwidth & scheduling Operator
D11 Watching what the house holds Household

E — Maintenance

ID Feature Audience
E1 Stack updates Operator
E2 Self-update Operator
E3 Backup & restore Operator
E4 Rollback Operator
E5 Changelog & release notes Operator

F — Extensibility

ID Feature Audience
F1 Customisation & escape hatches Operator
F2 Service catalogue Operator
F3 Plugin manifests Operator
F4 The capability vocabulary Operator
F5 The plugin catalogue and what vouches for a plugin Operator
F6 Plugin lifecycle Operator
F7 Plugin provenance Operator
F8 Recipes and named adapters Operator
F9 Capabilities of the bundled services Operator
F10 Writing a plugin Operator
F11 Executing contributed code Operator

G — Cross-cutting UX

These are not screens; they are properties every other feature must exhibit. G4 and G5 in particular are the connective tissue that makes the whole catalogue read as one product.

ID Feature Audience
G1 Interface tiers (CLI / TUI / web) Both
G2 Plain-language layer & in-product help Both
G3 Accessibility Both
G4 Error & remedy model Both
G5 The front door Both
G6 Client app guidance Household
G7 Overall health summary Operator
G8 Privacy stance Both
G9 Mobile client handoff Both

The ecosystem

Everything below ships before 1.0.0, on the same train as everything above it: authored to the same falsifiable-requirement bar, and gated by the same rule — no version ships a requirement it has not finished (OPS-R54). The through-line is the project’s wedge applied outward — not just wiring these services, but proving the wire works (a health check, a valid upstream credential, and a synthetic action read back), the thing no adjacent tool does.

Areas H, I and K are Accepted, as is F3. The runtime pillar (J) is Draft — proposed and open for comment: it reopens a non-goal (ADR-0010) and carries the most design risk, so it is not binding until reviewed.

H — Ecosystem glue

The tools the community bolts on, bundled and — the differentiator — verified.

ID Feature Audience
H1 Cross-seeding Operator
H2 Announce-driven grabbing Operator
H3 Quality-profile sync Operator
H4 Subtitles Both
H5 Queue self-healing Operator
H6 Library cleanup Both
H7 Transcoding Operator
H8 Playback statistics Both

I — Remote access & identity

Reaching the stack from outside the home, and the one-account gate it requires — both without a proprietary control plane.

ID Feature Audience
I1 Remote access for the household Both
I2 Household identity & single sign-on Both

J — Runtime & platform · Draft

Freeing the stack from a single container runtime, while keeping both proofs (VPN egress, hardlinks) passing on every engine (ADR-0010).

ID Feature Audience
J1 Container-engine abstraction Operator
J2 Running under Podman Operator
J3 Running natively, without containers Operator

K — Observability

Open-source-native metrics and monitoring — a second opinion, delivery-confirmed.

ID Feature Audience
K1 Metrics & dashboards Operator
K2 Uptime monitoring Operator

Also in existing areas: F3–F11 (the plugin system), B9 (open notification back-ends, extends B5), and G9 (mobile handoff, extends G6).

L — Release & distribution

Turning the built product into something a stranger can install and run. Each major release is its own scoped work — the distribution itself, not the features that came before it.

ID Feature Audience Ships in
L1 v1 release engineering Operator 1.0.0

N — Companion

The fourth surface, on a device that is not the one the stack runs on. One application for both audiences, deciding which by who signs in (ADR-0017).

Specified in full and locked by no version: the app follows what the main repositories have shipped rather than leading them, so nothing on the release train waits on it. It is pinned with the rest once it has caught up.

ID Feature Audience
N1 The companion app Both
N2 The operator’s companion Operator
N3 The household’s companion Household
N4 What the app uses of the device Both

Traceability

Three links, all of which CI checks:

Journey  ──exercises──▶  Feature  ──contains──▶  Requirement  ◀──implements──  Code
                                                      ▲
                                                      └──cites──  Architecture doc
  1. Every journey names the features it exercises.
  2. Every feature owns numbered requirements.
  3. Every architecture and per-repo doc cites the requirement IDs it satisfies.

A technical decision that cites no requirement is unjustified, and should be challenged in review. That’s the rule that keeps the technical spec written against the features rather than alongside them.