bd40c962cfcb33d435897e6451fab0522b6cfe44
Round 5, two independent reviews. Two findings, one technical and one about honesty, and the second is the more important. THE RATIONALE. The round-4 commit and the decision record state as measured fact that trapping signals made a hook take 30s to die where it took 1s. That came from a review finding I accepted without re-measuring. It is wrong. Measured A/B: signal the pid control 4.01s trapped 4.12s signal the group control 0.002s trapped 0.054s The stall is bash deferring a fatal signal until its foreground command finishes, and it happens identically with NO trap — the control stalls too. The trap cost ~0.1s, not 29s. The withdrawal still stands, but on its real grounds: three silent permissive-direction defects in three rounds for a sub-millisecond rescue window, and the trapped sink STILL returned rc 0 on SIGINT where the control returns -2. The record now carries the correction rather than the fabrication, because a decision record with an invented measurement reads as checked and talks the next reader out of checking. The test that was supposed to enforce this was itself vacuous: it signalled the pid, so both sides took the full sleep and the timing assertion could distinguish nothing. It signals the process group now — the supervisor shape, and the only one where the assertion can see anything. THE LOCALE FIX WAS INERT. `local LC_ALL=C` does not export, so the child sed/tr never saw it. It read as fixed only because this author's shell sets LANG alone; with an inherited LC_CTYPE (macOS Terminal, ssh SendEnv, sudo env_keep) LC_CTYPE outranks the exported LANG=C and the symptom returns in full — a real deny filed as `output`, records under `unknown-session` with empty event and tool, and `illegal byte sequence` at the harness. `local -x` now, verified end-to-end across four locale environments, and the test is parametrised over them because a single ambient locale tests one row of the matrix. Also this round: - Removing the 64KB cap ARMED a latent bug rather than fixing one: a greedy `.*` over a single-line payload takes the LAST match, so a nested session_id inside a tool_response outranked the top-level one and filed the whole invocation under the wrong session. The cap had been accidentally protecting the right answer. First-match extraction now, bounded at 256KB where the bound is no longer load-bearing (3 unbounded scans cost 1.5s on a 20MB payload). - A present-but-empty decision value was laundered to `output`. - The redirect-order guard excluded operators preceded by a digit, so it was blind to `exec 0<` — the exact line it was written for. Mutation-checked both ways now: clean on the real file, red when the original bug is reintroduced verbatim. Its limits are stated in the docstring rather than implied. Refs: #776 Decisions-Edit: yes Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
