You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
π€ Auto-generated by Claude Fable 5 (claude-fable-5) via Claude Code β NOT human-reviewed. Verify before acting. Claims marked β were re-verified against source by the model; the rest come from a model-written inventory of the feat/media-backend-v2-port branch (42e7e21).
Feature-complete roadmap
Tracking issue for taking ovos-media from "MediaBackend v2 train ready" to feature complete: every user story implemented, tested (unit + e2e), documented, live-validated, and audited. This body is the living state β it gets edited in place as items land.
Blocked on the release train
Everything in the "fix" sections below lands after OPM #442 merges and #194 follows (the train's commit sequence). Until then only harness, spec, docs, and audit work moves.
Coverage gaps (from the full user-story inventory)
Spec conformance (OCP-1):
β Skill can_seek declaration (Β§4.3.1) unimplemented: catalog/catalog.py never reads can_seek from ovos.common_play.announce, and SkillPlayerAdapter.seek() unconditionally warns-and-drops. Skill playback can never become seekable. Implement announce-side ingestion + conditional seek delegation + MPRIS CanSeek passthrough.
β Relative seek: RESOLVED as a spec amendment. An ecosystem sweep found no emitter uses the spec's position field β the deployed wire is seekValue (absolute ms, GUI seekbar) and seconds (signed relative, OCPInterface.seek_forward/seek_backward β the skill-facing API, a pre-spec surface with mandatory backcompat). Player-side resolution of seconds is atomic against live position, which is stronger against concurrent seekers than requester-side resolution from a stale state read; OCP-1 Β§4.2.2 is being rewritten to document both real shapes with the corrected rationale. ovos-pydantic-models' seek model (position) needs aligning to the wire.
Β§5 per-session isolation: RESOLVED β OCP-1 now states the registry MAY be satisfied by deployment topology (per-satellite embedded daemons; hub serves its local session). Originally: implementation is a binary default/non-default gate on a single player, relying on the one-daemon-per-satellite topology (documented in service.py). Spec text should state explicitly that the per-session registry MAY be satisfied by per-satellite daemon instances, or the gap is real.
ovos.common_play.register_keyword: RESOLVED β Β§4.1 carve-out for non-mutating advisory emissions (control requests in, registration hints) landed; state authorship stays the player's alone. Originally: Β§4.1's reservation wording doesn't carve out advisory non-mutating messages. Spec clarification.
Wrong-session behavior:
β Wire state reports (media.state/track.state from media_backends/base.py) are bare Message(topic, data) with no context.session β OCP-1 Β§4/Β§4.4 require the originating session so hub consumers can demultiplex (peer spec-audit finding, verified file:line). Fix together with the dialog-session item below: stash the requester's session at play time, derive all state reports and notifications from it.
β All spoken dialogs (track.failed, queue.finished, no.playback.backend, β¦) land on the default session even for satellite-triggered playback β acknowledged in skill.py's own docstring. Fix: stash the triggering message's session at play time and carry it through END_OF_MEDIA / INVALID_MEDIA / retry-timer paths.
Coverage holes:
PlaybackType.SKILL full-cycle e2e added on the v2 branch (5 cells: delegation verbs + wire states).
β Config live-reload: hot knobs (autoplay, validate_source with explicit-override precedence honored end-to-end incl. the voice skill, preferred_*_services) read live configuration; cold knobs pinned by an armed test (feat: hot-reload cheap media config knobsΒ #207, converged).
Shuffle/repeat/relative-seek/like-unlike e2e cells added on the v2 branch (+11 mutation-proofed, incl. a found-and-fixed unclamped negative-seek defect); MPRIS headless graceful-degrade verified live; MPRIS on by default with a Playlists stub and lifecycle logging, validated on a real bus (feat: MPRIS on by default with a Playlists stub and lifecycle loggingΒ #210, converged).
ovoscope v2 harness built and converged (ovoscope#168: MediaBackendHarness reporter-capture layer + OCPPlayerHarness v2 repair + v2 mock; three adversarial rounds + an executed two-venv gate). Held draft until the v2 train releases, then floors bump and it merges β un-skipping media-plugin e2e cells fleet-wide.
Remote backends (chromecast, mass, spotify, mpris) have review-verified v2 ports but no real-device live playback validation; remote verb confirmation (silently ignored pause on a dead device) needs a timeout/notify design.
Play counts only accumulate for already-liked tracks; ranking can never surface a heavily-played unliked track. Decide global play-count vs documented limitation.
Album/artist metadata intents mostly answer "no info" (MediaEntry has no album field). Decide enrich vs trim intents.
Docs: technical-manual one-story page + plugin migration guide (queued with the docs campaign, keyed to the v2 wire-changes table).
Validation plan
Several independent expert audits (concurrency on the dispatcher/lock model, UX on voice flows, adversarial on the merged train) and user-persona runs (fresh-install quickstart verbatim, satellite user, desktop MPRIS user), each producing findings triaged into this list.
Final gate: voice-driven live round trip on released packages only, incl. restart/network-kill/bad-stream recovery on all three namespaces.
Feature-complete roadmap
Tracking issue for taking ovos-media from "MediaBackend v2 train ready" to feature complete: every user story implemented, tested (unit + e2e), documented, live-validated, and audited. This body is the living state β it gets edited in place as items land.
Blocked on the release train
Everything in the "fix" sections below lands after OPM #442 merges and #194 follows (the train's commit sequence). Until then only harness, spec, docs, and audit work moves.
Coverage gaps (from the full user-story inventory)
Spec conformance (OCP-1):
can_seekdeclaration (Β§4.3.1) unimplemented:catalog/catalog.pynever readscan_seekfromovos.common_play.announce, andSkillPlayerAdapter.seek()unconditionally warns-and-drops. Skill playback can never become seekable. Implement announce-side ingestion + conditional seek delegation + MPRISCanSeekpassthrough.positionfield β the deployed wire isseekValue(absolute ms, GUI seekbar) andseconds(signed relative,OCPInterface.seek_forward/seek_backwardβ the skill-facing API, a pre-spec surface with mandatory backcompat). Player-side resolution ofsecondsis atomic against live position, which is stronger against concurrent seekers than requester-side resolution from a stale state read; OCP-1 Β§4.2.2 is being rewritten to document both real shapes with the corrected rationale. ovos-pydantic-models' seek model (position) needs aligning to the wire.service.py). Spec text should state explicitly that the per-session registry MAY be satisfied by per-satellite daemon instances, or the gap is real.ovos.common_play.register_keyword: RESOLVED β Β§4.1 carve-out for non-mutating advisory emissions (control requests in, registration hints) landed; state authorship stays the player's alone. Originally: Β§4.1's reservation wording doesn't carve out advisory non-mutating messages. Spec clarification.Wrong-session behavior:
media.state/track.statefrommedia_backends/base.py) are bareMessage(topic, data)with nocontext.sessionβ OCP-1 Β§4/Β§4.4 require the originating session so hub consumers can demultiplex (peer spec-audit finding, verified file:line). Fix together with the dialog-session item below: stash the requester's session at play time, derive all state reports and notifications from it.track.failed,queue.finished,no.playback.backend, β¦) land on the default session even for satellite-triggered playback β acknowledged inskill.py's own docstring. Fix: stash the triggering message's session at play time and carry it through END_OF_MEDIA / INVALID_MEDIA / retry-timer paths.Coverage holes:
PlaybackType.SKILLfull-cycle e2e added on the v2 branch (5 cells: delegation verbs + wire states).Product polish:
repeat.setmode), relative seek, shuffle state, and a bounded what's-next preview (spec'd Β§4.4.1next_track/next_track_hint) β feat: voice intents for like, repeat, seek, shuffle state and queue peekΒ #209, converged.MediaEntryhas no album field). Decide enrich vs trim intents.Validation plan