Handoff: Disable and hide synced lyrics¶
Date¶
2026-07-13
Summary¶
The opt-in synchronized-lyrics feature is now disabled and hidden. YouTube Music provides native time-synced lyrics, so ours is redundant. This removes the only user path to the feature and the network permission it needs, while keeping the feature code and its setting so the decision is cheaply reversible. No hard invariant changed: logged-out only, credentialless ANDROID_VR, PlayerHandle as the sole <video>.src writer, fail-open to native playback, and the page-world trust boundary all hold. Loudness normalization and the equalizer remain the active YouTube Music extras.
Branch rebuild, PR #65.
Decision¶
YouTube Music already shows native, time-synced lyrics. Shipping our own LRCLIB-backed panel on top of that duplicates a first-party feature, so it is retired from the product surface. It is disabled rather than deleted so it can be brought back cheaply if the calculus changes (for example on plain youtube.com, where there is no native equivalent).
What changed¶
- Options toggle removed (
entrypoints/options/App.tsx). The "Synced lyrics" row, its label, description, and search-visibility wiring are gone, so the feature is not reachable from any UI (the popup never exposed it). lrclib.nethost permission dropped (wxt.config.ts).https://lrclib.net/*is removed from both the MV2permissionsand the MV3host_permissions, so the background can no longer fetch lyrics even if the setting were on.- Feature code kept.
entrypoints/content.ts,entrypoints/main-world.ts,entrypoints/background.ts, andsrc/shared/lyrics.tsare unchanged, and thelyricsEnabledsetting (defaultfalse) stays insrc/shared/config.ts. The change is reversible.
Docs updated¶
docs/specs/SPEC-007-m4-youtube-music-extras.md: marked the Lyrics section disabled and hidden with the rationale and the retained-code note, and adjusted the Overview, Goals, Settings, Testing Strategy, Rollout, and Security sections. Loudness normalization and the equalizer are the active M4 extras.README.md: removed the Synced lyrics feature row and the defaults-summary mention.docs/release-notes/NEXT.md: dropped the "Lyrics that behave" bullet and the synced-lyrics clause from the YouTube Music line.CLAUDE.md,AGENTS.md,mkdocs.yml: dropped "lyrics" from the product feature-set description.
Verification¶
- Options regression test (
tests/unit/ui/options.test.tsx): a new lock asserts the "Synced lyrics" row is absent (#option-lyricsis not rendered), the text "Synced lyrics" is not present, and a search for "lyrics" matches nothing and shows the empty-search status. The switch-count and description-count assertions drop by one accordingly. - Manifests have zero
lrclib. MV2 and MV3 builds were inspected: neither the MV2permissionsnor the MV3host_permissionscontainslrclib.net. - Bench 48/48 unaffected. The bench seeds
lyricsEnableddirectly through storage (not the UI) and its lyrics fetch targets the local fixture origin permitted by the bench-only match patterns, notlrclib.net, so dropping thelrclib.netpermission does not change any bench outcome. - Unit totals: 245 passed (was 244; net +1 from the new regression test). Full gate:
npm run validate.
Known issues / notes¶
- No migration for a persisted
lyricsEnabled: true. A profile that had opted in keeps the storedtrue; it is not migrated tofalse. That is harmless: with thelrclib.netpermission removed the background cannot fetch and there is no UI, so nothing renders. The extension is also not yet released, so no field profile carries this state. - Matrix assertion was left stale (fixed in a follow-up). This change updated the smoke bench but not the settings-permutation matrix (
tests/e2e/bench/run-matrix.mjs), whoselyricsEnabledcase still expected lyrics to render when a combo seeds it true. Eight matrix combos therefore failed ("lyrics on: not rendered") and, because CI runs the matrix, that job went red. A follow-up flips the assertion to a kill-switch lock (lyrics must never render regardless of the seeded value).
Next steps¶
- If lyrics is ever revived, restore the
lrclib.netpermission and the options toggle, and prefer scoping it to surfaces without native lyrics (plainyoutube.com).