4164efbc3ed1d28e2bdc32038544e64937eef06a
A fifth cold review confirmed the gate's behaviour is correct and proof-backed, and blocked on three non-behavioural items. All three fixed; none touches the shipped logic. MEDIUM — the round-7 fixture narrated a raced human verdict it did not construct. `null-page1-after-post` appended the row unconditionally, so it also joined the PRE-write read and lifted the high-water mark above itself; removing it changed nothing. The reviewer's suggested fix was to gate the append on the post-write read. Measured after gating: still inert, because page 1 answers `null` before any row reaches the wire. So the row is gone rather than gated, and the prose now describes what the fixture actually poses: a response asserting an empty history for a sha this job wrote to must not be accepted as proof that nothing raced. Whether a verdict really raced is not modelled and does not need to be — the response is not evidence either way. A row the test cannot observe is decoration that reads as coverage, which is the same class this branch has now been blocked on five times. LOW — the comment claimed the predecessor "at least produced a `::warning::`". Half false, measured against `origin/main`: its `jq -e 'type == "array"'` gate ACCEPTED `[]` silently and warned only on `null`. What is actually new is that the paged walk reports such a read as a SUCCESS. LOW — when the empty clause fired it set `ph_ok=no`, so the log said "could not be read completely" beside a walk that completed on a validated terminator. The answer was impossible, not unreadable, and an operator holding a sticky sentinel needs to know which. It now carries its own `raced_why`, asserted by the test. Both clauses mutation-proved: disarming the empty check, and reverting to the borrowed wording, each redden the named test. Verification: `scripts/tests` 1097 passed, 2 skipped; decisions_validate and build_decisions_catalog --check exit 0. refs #763 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fix(787): derive the dropped-step guard's scope, and reconcile its snapshot against the server (#861)
fix(754,757): declare graphicsElementIds + padToNearestMinute, and pin every MCP tool to its OpenAPI contract (#760)
fix(754,757): declare graphicsElementIds + padToNearestMinute, and pin every MCP tool to its OpenAPI contract (#760)
ErsatzTV
ErsatzTV lets you transform your media library into a personalized, live TV experience - complete with EPG, channel scheduling, and seamless streaming to all your devices. Rediscover your content, your way.
How It Works
- Install ErsatzTV: Download and set up the server on your system.
- Add Your Media: Connect your media libraries and collections.
- Create Channels: Design and schedule your own live channels.
- Stream Anywhere: Watch on any device with IPTV and EPG support.
Key Features
- Custom channels: Create and schedule your own live TV channels.
- IPTV & EPG: Stream with IPTV and Electronic Program Guide support.
- Hardware Transcoding: High-performance streaming with hardware acceleration (NVENC, QSV, VAAPI, AMF, VideoToolbox)
- Media Server Integration: Connect Plex, Jellyfin, Emby and more.
- Music & Subtitles: Mix music videos and enjoy subtitle support.
- Open Source: Free, open, and community-driven project.
Documentation
Documentation is available at ersatztv.org.
License
This project is inspired by pseudotv-plex and the dizquetv fork and is released under the zlib license.
