From b1d6034662470cfa69700254cc7f63f1341dcd7b Mon Sep 17 00:00:00 2001 From: gramps Date: Thu, 22 Oct 2026 06:51:04 -0700 Subject: [PATCH] TASK 55 slice 1: the startup log is size-capped The creator (2026-10-09): 'we need some sort of log-rotation so that we don't inadvertently fill up a user's drive.' startup.log was uncapped - 23MB and growing every few seconds, because FfmpegEncoder logs every non-progress ffmpeg stderr line. The policy lives in a new Helpers/LogRotation.cs as a pure function over a path (RollIfNeeded(logPath, maxBytes, retainedFiles)), so AppLog's 156 call sites keep their surface and the rule is testable on its own. At 5MB the live file rolls to startup.1.log and one rolled copy is kept - the FILE SET is bounded, not just the live file, so a long stream cannot grow the log without limit. A failed rotation degrades to the old behaviour instead of taking the app down. Pattern reference (cited): Serilog's file sink pairs fileSizeLimitBytes (the cap) with retainedFileCountLimit (how many rolled files to keep) - https://github.com/serilog/serilog-sinks-file Guard: ytLive.Tests/AppLogRotationTests.cs - the ONE test drives the real AppLog.Write against a temp dir (two internal seams: PathOverride, MaxBytes) and asserts the roll, the fresh live file, and that after a SECOND roll the directory still holds exactly startup.log + startup.1.log. Also fixed a stale catalog row: TASK 12 (master limiter) shipped 2026-08-15 and was still marked 'Queued'. --- HANDOFF.md | 22 +++++++--- Helpers/AppLog.cs | 22 ++++++++-- Helpers/LogRotation.cs | 63 +++++++++++++++++++++++++++ Helpers/index.md | 3 +- MyMistakes.md | 22 ++++++++++ TASKS.md | 4 +- TASKS/task-55-disk-hygiene.md | 11 ++++- ai.md | 2 +- ytLive.Tests/AppLogRotationTests.cs | 66 +++++++++++++++++++++++++++++ 9 files changed, 201 insertions(+), 14 deletions(-) create mode 100644 Helpers/LogRotation.cs create mode 100644 ytLive.Tests/AppLogRotationTests.cs diff --git a/HANDOFF.md b/HANDOFF.md index 6783cba..b99f33a 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -70,6 +70,13 @@ `ytLive.Tests/BorderColorPickerTests.cs` (model + panel + the **real widget**). The TASK 60 guard (`BorderColorPaletteTests`) was updated to guard the new wiring (the drop-down is bound to the palette; no second list of colours anywhere). +- **TASK 55 slice 1 — the log is capped (shipped 2026-10-22).** `startup.log` was uncapped (23 MB + and growing every few seconds — ffmpeg logs every stderr line). Now it rolls to `startup.1.log` + at 5 MB (one rolled copy kept), so the growth is bounded. The policy is + `Helpers/LogRotation.cs` (a pure function over a path — `AppLog`'s 156-call-site surface is + unchanged; the seams are two `internal` properties). Guard: + `ytLive.Tests/AppLogRotationTests.cs`. Slices 2 (temp alert-clip cleanup) and 3 (low-disk + guard before recording) are still open. - **The previous session (HA lights) produced NO ytLive code** — it was spent on the creator's Home Assistant light alert system (off-repo, `192.168.50.145`). See `MyMistakes.md` → 2026-10-21: the plan was one tweak to a verified-working script; the script was rewritten twice, the alert path broke, and @@ -258,13 +265,15 @@ Zombie entities deleted from the registry: `script.leak_strobe`, `script.doorbel `Helpers/OAuthCredentials.cs` were never tracked. ⚠️ the repo was **already public** (anonymous GET → 200, API `private = false`) when the scan ran — the gate came late, but nothing leaked. Method + verdict: `TASKS/task-56-secret-scan.md`. -- TASK 55 disk hygiene (`startup.log` uncapped — 23MB and growing every 5s). +- TASK 55 disk hygiene: slice 1 (log rotation) **shipped 2026-10-22** — see the At-a-glance bullet. + Slices 2 (temp alert-clip cleanup) + 3 (low-disk guard before recording) are open. (The GOG + Galaxy `cef.log` at 2.7 GB is NOT ours.) ## Tests -- Last full run: **435/435 passed, 0 warnings** (2026-10-21, this session — after TASK 63's - `BorderColorPickerTests`, which replaced TASK 62's `BorderColorNameTests`; the run before was also - 435/435 after TASK 61+62, and the runs before that were 433/433 after TASK 60, 432/432 after - TASK 59 and 431/431 after TASK 58). The one failure seen earlier in the +- Last full run: **436/436 passed, 0 warnings** (2026-10-22 — after TASK 55 slice 1's + `AppLogRotationTests`; the run before was 435/435 after TASK 63, and the runs before that were + 435/435 after TASK 61+62, 433/433 after TASK 60, 432/432 after TASK 59 and 431/431 after + TASK 58). The one failure seen earlier in the session was `LayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorder`, which **passes in isolation** (re-run: 3/3) — the known real-mouse flake, not a regression. - Known flaky-by-environment (all pass in isolation): `AudioPipelineTests.Mix_HonorsProviderGains…`, @@ -279,7 +288,8 @@ Zombie entities deleted from the registry: `script.leak_strobe`, `script.doorbel ## Secrets / paths (do not re-hunt) - Layout DB: `%APPDATA%\ytLlive\ytLlive.db` (SQLite, full-rewrite per save). Auth: - `%APPDATA%\ytLlive\ytLlive.auth` (DPAPI). Startup log: `%APPDATA%\ytLlive\startup.log` (23MB). + `%APPDATA%\ytLlive\ytLlive.auth` (DPAPI). Startup log: `%APPDATA%\ytLlive\startup.log` + (23MB — now CAPPED at 5 MB with one rolled copy, TASK 55). - Recordings land in `C:\Users\gramp\Downloads\recordings\` (`ty--