DR-244. The first real engine on the contract, and the tooling to interrogate
it in isolation.
The point of difference from MpvBackend is `open`: the start position is
applied at load time via mpv's own `start` option, instead of being seeked to
afterwards. loadfile is asynchronous, so a seek issued after it targets a
player with nothing loaded, fails, and was discarded. A seek that does arrive
during Opening is held and applied on FileLoaded, so no caller has to know
where that window begins or ends.
`close` clears state before issuing the stop, so an open still in flight
checks it on FileLoaded and cannot proceed to play after the caller has
stopped it. It is idempotent: callers legitimately close twice on teardown.
Every property the event loop matches is observed, per DR-239.
The runner is a separate binary that links libmpv and nothing else, so a
wrapper can be verified without building or launching the app — which is what
made the previous round of playback debugging so slow. Audio and video go to
null, so it is safe on a headless runner and does not claim the speakers. It
lives behind a `conformance` feature and exposes one entry point rather than
making the player module tree public.
cargo run --features conformance --bin player-conformance -- <media-file>
All nine cases pass against real libmpv. Verified the suite can fail: reverting
`open` to the old load-then-seek behaviour makes opens_at_a_start_position fail
and restoring it makes it pass, so DR-241 is now a test rather than an
anecdote.