Mark roadmap A1 (tests/CI) and A2 (subprocess hardening) done

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-06-04 23:53:19 -07:00
parent 46c6d162a0
commit 00fdbd50df

View file

@ -6,25 +6,20 @@ it exists. Checkboxes track status.
## Phase A — Safety net & correctness (do first) ## Phase A — Safety net & correctness (do first)
- [ ] **A1. Automated test suite (pytest).** The project has no tests today; - [x] **A1. Automated test suite (pytest).** DONE — `tests/` with 43 headless
every change is hand-verified. Start with the pure logic that already tests covering the split planner + chapter helpers,
isolates cleanly: `compute_high_profile_bitrate`, ffmpeg command generation (profiles,
- `plan_disc_split`, `_movie_chapter_seconds`, `_nearest_chapter_before` text/image hardsub, 2-pass, even pad/crop, AC3 448k, progress-to-file,
- `compute_high_profile_bitrate` `-ss`), ffprobe subtitle detection, and executor I/O. CI in
- ffmpeg/avconv command generation (`convert_file``command_var`) with `.forgejo/workflows/tests.yml`. Caught/guards the 448k→384k clamp bug.
mock `file_project` objects, asserting flags for each profile,
text/image hardsub, 2-pass, even pad/crop, AC3 448k.
Add a `tests/` dir and a CI workflow (Codeberg Actions/Woodpecker). This
would have caught the 448k→384k clamp bug automatically.
- [ ] **A2. Harden subprocess I/O (kills the deadlock class).** `executor` - [x] **A2. Harden subprocess I/O (kills the deadlock class).** DONE — the
reads child stdout/stderr via blocking `GLib.IOChannel` watches; a stalled executor now drains child stdout/stderr with background reader threads
consumer can backpressure-deadlock the child (this bit us — ffmpeg froze into thread-safe buffers, consumed by a GLib timer on the main thread, so
on a full progress pipe when the GUI wedged). The progress-file fix only a stalled/wedged main loop can never backpressure-deadlock a child on a
covers ffmpeg progress; dvdauthor/spumux/mkisofs stdout/stderr still use full pipe. stdout can go straight to a file, stdin is fed from a thread,
the fragile pattern. Build one hardened helper (non-blocking reads, the retained log is bounded, and `wait_end` runs once. Verified a 2MB-
drain-on-close, bounded buffers, never let a child block on a pipe we own) output child completes with the main loop never running.
and route every backend through it.
- [ ] **A3. Surface real errors to the user.** Failures show a generic error - [ ] **A3. Surface real errors to the user.** Failures show a generic error
window; the actual failing command + stderr is buried in the log. On window; the actual failing command + stderr is buried in the log. On