feat(55): stop leaving disk debts — temp clips and a low-disk guard

595 green, 0 warnings. Completes TASK 55 (slice 1, log rotation, shipped 2026-10-22).

- **`AlertClipCleanup`**: the default alert clip is materialised into `%TEMP%` for ffmpeg to read, and
  nothing ever deleted it — one orphan per profile that ever played an alert. Now: delete this session's
  file in `Shutdown`, and sweep `ytLive-alert-*.mp4` at startup for anything a crash left behind. Only
  the prefix we own is touched; a directory is never deleted.
- **`DiskSpaceGuard`**: a recording that dies of a full disk is a trust breach, so the numbers are a
  pure policy — refuse to start under **1 GB** (toast; the stream still starts, recording does not),
  warn under **5 GB** at start ("about eighty minutes" at 8 Mbps ≈ 3.6 GB/h), and one mid-show warning
  under **2 GB** — the last useful moment before the encoder fails for a reason it won't explain.
  Unreadable drives (a USB stick that just left) return null and never block a running recording.

Tests are policy-level on purpose: filling a real drive is not a test. `DiskHygieneTests` proves the
sweep only removes our own files and that the thresholds behave at both ends.
This commit is contained in:
2026-11-10 11:55:42 -08:00
parent c257de1516
commit 1a6a549e17
9 changed files with 222 additions and 5 deletions
+2 -2
View File
@@ -9,7 +9,7 @@
**Creator ruling 2026-11-09 — finish the queue before the new features, gold pass always last.**
`37 → 40·A/C/D → 55·2–3 → Move → 9·5 → 14 (slices) → 65 → 66 → 67 → 68 → 36`
`37 → 40·A/C/D → Move → 9·5 → 14 (slices) → 65 → 66 → 67 → 68 → 36`
The rule behind the two retirements below: **do not rebuild the platform's own surface.** Scheduling,
publishing, moderation and channel management are YouTube's; the app owns capture → scene → sound →
@@ -22,7 +22,7 @@ output.
| 35 | ✅ | **Scene-linked audio** — the scene remembers the room: BRB ships muted, three-state checkboxes per scene, applied once when the scene takes the program output (done 2026-11-10) | [`task-35`](TASKS/task-35-scene-linked-audio.md) |
| 37 | ☐ | **Defaults vs current layout split** — separate branded defaults from the live workspace; enables one-click revert | [`task-37`](TASKS/task-37-defaults-current-split.md) |
| 40·A/C/D | ☐ | **Settings round** — active-camera picker; persist output resolution + surface transition defaults + confirm-before-End; accent consolidation | [`task-40`](TASKS/task-40-app-settings-round.md) |
| 55·2–3 | ☐ | **Disk hygiene** — delete `%TEMP%` alert clips on close + sweep at startup; low-disk guard before REC (slice 1 shipped) | [`task-55`](TASKS/task-55-disk-hygiene.md) |
| 55 | ✅ | **Disk hygiene** — log rotation (5 MB, one roll), temp alert clips deleted on close + swept at startup, low-disk guard (block under 1 GB, warn under 5 GB at start, one warning under 2 GB mid-show) — done 2026-11-10 | [`task-55`](TASKS/task-55-disk-hygiene.md) |
| — | ☐ | **Move transition** — per-layer carry-across-scenes flag, per-scene placement, fixed z band | [`ui-surface`](docs/ai/ui-surface.md) |
| 9·5 | ☐ | **Webcam identity key reconciliation** — one stable identity per camera across re-plugs | [`task-09`](TASKS/task-09-live-stream-management.md) |
| 14 | 🔶 | **Creator feedback batch** — Branch 2 shipped; Branch 3 = mic input gain, webcam blank/standby, opacity+geometry consistency, Show-in-folder on stop | [`task-14`](TASKS/task-14-creator-feedback-batch.md) |