dabbd4c3e86bf3531fade5b2de3361b49761efac
Two independent cold reviews (one cross-family) blocked the previous revision, both on the same defect the section exists to name: a zero read as "unused" without checking whether the thing was switched on. They were right. serena was not "reachable all along". It was `false` in ~/.claude/settings.json until 2026-08-14T12:31Z, when a concurrent session enabled it; its tools appear in no transcript before 12:42:54Z that day. The #799 session had started at 12:01Z and never ran /reload-plugins, so its probe at 13:41Z correctly reported the tools absent — while the settings file already said `true`. Both reviewers had half of this; the reload boundary is what reconciles them, since the session that performed the toggle DID acquire serena mid-run after reloading three times. So #799's observation was accurate and its cause is now established, rather than refuted as the previous revision claimed. The error underneath it was dating transcript evidence by file mtime instead of record timestamp, which places a session's records at the moment it last wrote and made a first-appearance look like a pre-existing state. Both rules are now recorded in the section. Six of the eight plugins called "genuinely unused" were disabled for 16 of the 30 corpus days (settings.json.bak-doctor), and ralph-loop is not unused at all — its Stop hook has 1,083 executions, the same cadence as security-guidance, since both fire on every stop. It is the sole enabled plugin owning hooks/stop-hook.sh, so the attribution is unambiguous. That is a fourth instance of the wrong-surface mistake, found in the act of documenting the first three. Also: "256 codex exec calls" counted Bash inputs *containing* the string, including pgrep and echo; at command position it is 117. The surface list no longer claims a fixed count, omits neither `LSP` nor `attributionSkill`, and says what was not separately identified. In local-lsp-tooling.md the subagent claim is marked expected-but-undemonstrated, "the only surface not C#-only" is dropped as false, ~30 language servers becomes the config's actual 73, and the multi-minute warm-up assertion is replaced by the one cold run's real timings. 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(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)
fix(787): derive the dropped-step guard's scope, and reconcile its snapshot against the server (#861)
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.
