Three corrections to the Linux native-video spike, each of which reverses something recorded earlier in the same session: - The crash is unexplained. It was first blamed on hwdec=auto-safe's Vulkan failures, on a misreading of the logs — those are two per run at start-up, not per-frame, and every clean run has the same two. A 300s soak on auto-safe survived. So did 240s of automated fullscreen toggling (~120 transitions) and 240s of continuous resizing (~2000 reallocations). Three hypotheses, none reproduced. Recorded rather than dismissed: an intermittent fault nobody can reproduce is worse to inherit than a deterministic one. - G5 drops to amber. It looked and felt smooth, but the only SIGSEGV observed came from the only session in which fullscreen was exercised, and the spike has no lifecycle handling at all — it never frees the render context. An implementation must bind that to the GL context's lifetime regardless of what caused this crash, because Android already paid for that lesson as DR-184. - Finding 3's premise is in doubt. "The webview path already has real ABR via hls.js" was never checked against the URLs this app builds: get_video_stream_url requests a single rendition, the frontend has no level-handling code at all, and a quality switch is implemented by re-opening the stream. If the playlist is single-variant there is no adaptation to lose. The decisive test needs a live server and is recorded as unrun. Also records hardware decode working through the render API (nvdec-copy engaged), and that hwdec=vaapi silently fell back to software on this box.
Specs index
Feature specs for JellyTau. Start a new one from SPEC-TEMPLATE.md and run it past 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/. 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 before allocating): UR-079, IR-033, DR-219. 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 | Catalog surface: MediaKind, from_jellyfin isolated, ticks → ms |
primaryImageTag → imageId (~30 sites); player/session/reporting tick math; stream.type |
| libmpv2-migration.md | LICENSE |
The libmpv → libmpv2 crate swap |
| read-through-media-cache.md | DR-126…128, DR-133…138 — cache entries are download rows; local playback of downloads | DR-121/122/124/125 — the player quality selector and the read-through capture |
| 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 |
|---|---|
| build-provenance.md | build.rs is still bare. ⚠️ suggested id DR-093 is taken. |
| 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 | Blocked on the libmpv2 swap. ⚠️ suggested id IR-030 is taken. |
| 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. Needs an implementation spec that answers adaptive bitrate. |
Design authority
| Spec | Role |
|---|---|
| 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 | The boundary design the check:boundary rule came from. Stage 1 built. |
| 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 — App Shell and Chrome |
| Library mosaic | 02-svelte-frontend.md — Library Mosaic |
| Series current-episode navigation | 02-svelte-frontend.md — Series and Episode Navigation |
| Downloads as an offline library | 02-svelte-frontend.md — Downloaded Browse |
| Favourites browsing | 01-rust-backend.md — Favorites System |
| Streaming bitrate cap | 01-rust-backend.md — Streaming quality ladder |
| Locally-indexed search | 03-data-flow.md — Search Flow; 01-rust-backend.md — Background workers |
| Offline downloaded-only filter | 06-downloads-and-offline.md — Offline Catalog Visibility |
| Audio equalizer · Android audio settings parity | 05-platform-backends.md — Audio settings on ExoPlayer |
| Android native video spike | 05-platform-backends.md — Native Video Compositing |
| Video background audio | 05-platform-backends.md — Background Audio Handoff |
| Traceability gate repair | 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 |