Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m59s
Traceability Validation / Check Requirement Traces (push) Successful in 19s
Build & Release / Run Tests (push) Successful in 15m32s
Build & Release / Build Linux (push) Successful in 21m6s
Build & Release / Build Windows (push) Successful in 16m45s
Build & Release / Build Android (push) Failing after 18m8s
Build & Release / Create Release (push) Skipped
CI caught this, which is what it is for: `check-doc-links.sh` failed because
media-player-controller.md links to backend-owned-stream-selection.md twice and
the file was not on master.
My fault, and worth recording how. That spec was written and committed directly
on master early on, before the work moved into a worktree. Squashing the branch
began with `git reset --hard` back to the merge base, which dropped those early
master-only commits — and the squash then brought in a document referencing one
of them.
Nothing was lost: the commits are still reachable, and the file is restored from
1d56517f along with its index entries in docs/specs/README.md and the docs site.
The lesson is narrower than "be careful with reset": a squash whose base is
chosen by hand silently drops anything committed outside the branch being
squashed. Only the link checker noticed, because it is the one gate that reads
across files rather than within them — and it is also the one gate I had not
run locally before pushing.
All CI checks now pass locally: boundary, doc links, tooling, format, lint at
the 158 ceiling, traces validate, coverage 90%.
83 lines
6.0 KiB
Markdown
83 lines
6.0 KiB
Markdown
# Specs index
|
|
|
|
Feature specs for JellyTau. Start a new one from
|
|
[SPEC-TEMPLATE.md](SPEC-TEMPLATE.md) and run it past
|
|
[SPEC-REVIEW-CHECKLIST.md](SPEC-REVIEW-CHECKLIST.md) before accepting it.
|
|
|
|
## What lives here
|
|
|
|
**Only work that has not shipped.** Once a spec is fully implemented its design
|
|
is folded into the architecture docs — which are the maintained description of
|
|
the build — and the spec file is deleted. Git history keeps the original,
|
|
including its rejected alternatives and acceptance criteria; the architecture
|
|
docs keep the reasoning that a future change still needs.
|
|
|
|
So: a file in this directory is a **promise, not a description**. If you want to
|
|
know how something *works*, read
|
|
[docs/architecture/](../architecture/README.md). If you want to know what is
|
|
*planned*, read here.
|
|
|
|
**Status vocabulary**
|
|
|
|
| Status | Meaning |
|
|
|---|---|
|
|
| Proposed | Written, not accepted. Nothing built. |
|
|
| Accepted | Agreed as the design; implementation not started or not finished. |
|
|
| Partially implemented | Some parts shipped; the spec names what is left. |
|
|
| Design authority | No code of its own — it records a decision later specs act on. |
|
|
|
|
**Next free requirement ids** (always re-check
|
|
[requirements.md](../requirements.md) before allocating): **UR-079**,
|
|
**IR-033**, **DR-232**. Three specs below suggested ids that have since been
|
|
taken by other work; each carries a ⚠️ note at the top.
|
|
|
|
## Partially implemented
|
|
|
|
| Spec | What landed | What is left |
|
|
|---|---|---|
|
|
| [frontend-domain-model.md](frontend-domain-model.md) | Catalog surface: `MediaKind`, `from_jellyfin` isolated, ticks → ms | `primaryImageTag` → `imageId` (~30 sites); player/session/reporting tick math; `stream.type` |
|
|
| [libmpv2-migration.md](libmpv2-migration.md) | `LICENSE` | The `libmpv` → `libmpv2` crate swap |
|
|
| [read-through-media-cache.md](read-through-media-cache.md) | DR-126…128, DR-133…138 — cache entries *are* download rows; local playback of downloads | DR-122/124/125 — the read-through capture. DR-121 shipped as backend-owned stream selection and left this spec |
|
|
| [scoped-search-boundary-implementation.md](scoped-search-boundary-implementation.md) | Stage 1: `SearchScope` owned by Rust (DR-063…067) | Stage 2: result-side grouping (`GROUP_ITEM_TYPES` still in `searchScope.ts`) |
|
|
|
|
## Not started
|
|
|
|
| Spec | Blocked on / note |
|
|
|---|---|
|
|
| [desktop-native-video.md](desktop-native-video.md) | mpv draws video on every desktop platform, then the webview `<video>` path and hls.js are deleted. Converts a measured 7% direct-play rate toward Android's 85%. Stacked on backend-owned stream selection. |
|
|
| [backend-owned-stream-selection.md](backend-owned-stream-selection.md) | Rust owns direct-play-vs-transcode, transport and quality; players consume one `StreamSelection`. Partly built — `StreamSelection`, `Transport` and the `.m3u8` sniff removal have landed. |
|
|
| [build-provenance.md](build-provenance.md) | `build.rs` is still bare. ⚠️ suggested id DR-093 is taken. |
|
|
| [player-facade-enforcement.md](player-facade-enforcement.md) | ~60 `commands.player*` sites still outside the facade; no lint rule. ⚠️ suggested id DR-095 is taken. |
|
|
| [windows-native-audio-backend.md](windows-native-audio-backend.md) | Blocked on the libmpv2 swap. ⚠️ suggested id IR-030 is taken. |
|
|
| [linux-native-video-spike.md](linux-native-video-spike.md) | **Spike run 2026-08-21: compositing works on Linux, X11 and Wayland.** G1-G6 green bar the Tauri `default_vbox()` half of G1. The adaptive-bitrate question it was waiting on is **answered**: the server publishes one `EXT-X-STREAM-INF`, so there is no ladder for mpv to lose (DR-229). `StreamSelection` (DR-225) is the contract to consume. |
|
|
|
|
## Design authority
|
|
|
|
| Spec | Role |
|
|
|---|---|
|
|
| [playback-backend-unification.md](playback-backend-unification.md) | Why video cannot unify onto one native engine and audio can. The audio half has since shipped on Android; Windows has not. |
|
|
| [scoped-search-boundary.md](scoped-search-boundary.md) | The boundary design the `check:boundary` rule came from. Stage 1 built. |
|
|
| [scoped-search.md](scoped-search.md) | Superseded in part — its "frontend only, no Rust changes" decision is the leak the boundary spec reversed. UX still current. |
|
|
|
|
## Where the shipped specs went
|
|
|
|
Sixteen specs were folded into the architecture docs and deleted (2026-08-21).
|
|
Where to look for each:
|
|
|
|
| Shipped work | Now documented in |
|
|
|---|---|
|
|
| Account menu & global chrome | [02-svelte-frontend.md](../architecture/02-svelte-frontend.md) — App Shell and Chrome |
|
|
| Library mosaic | [02-svelte-frontend.md](../architecture/02-svelte-frontend.md) — Library Mosaic |
|
|
| Series current-episode navigation | [02-svelte-frontend.md](../architecture/02-svelte-frontend.md) — Series and Episode Navigation |
|
|
| Downloads as an offline library | [02-svelte-frontend.md](../architecture/02-svelte-frontend.md) — Downloaded Browse |
|
|
| Favourites browsing | [01-rust-backend.md](../architecture/01-rust-backend.md) — Favorites System |
|
|
| Streaming bitrate cap | [01-rust-backend.md](../architecture/01-rust-backend.md) — Streaming quality ladder |
|
|
| Locally-indexed search | [03-data-flow.md](../architecture/03-data-flow.md) — Search Flow; [01-rust-backend.md](../architecture/01-rust-backend.md) — Background workers |
|
|
| Offline downloaded-only filter | [06-downloads-and-offline.md](../architecture/06-downloads-and-offline.md) — Offline Catalog Visibility |
|
|
| Audio equalizer · Android audio settings parity | [05-platform-backends.md](../architecture/05-platform-backends.md) — Audio settings on ExoPlayer |
|
|
| Android native video spike | [05-platform-backends.md](../architecture/05-platform-backends.md) — Native Video Compositing |
|
|
| Video background audio | [05-platform-backends.md](../architecture/05-platform-backends.md) — Background Audio Handoff |
|
|
| Traceability gate repair | [traceability-ci.md](../traceability-ci.md) |
|
|
| Boundary tripwire hardening | `scripts/check-frontend-boundary.sh` (its header is the spec) |
|
|
| Playback docs corrections · req-coverage script removal | Nothing to document — both were corrections that have been applied |
|