Files
ersatztv/docs/handoffs/chicorytv-issue-queue.md
T
timothyandClaude Opus 4.8 2998d1c2b9
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 8m9s
Build ErsatzTV Image / Docs update reminder (push) Has been skipped
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Failing after 18m35s
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
docs: mark CI runner fixed (server-management#570, verified run #371) + log NU1903 triage
Cache-save hang resolved: run #371 test log shows actions/cache restore (732MB NuGet) +
save (~1s) + hit-skip working; warm Build&test ~9min. Record the Microsoft.OpenApi 2.0.0
(NU1903/GHSA-v5pm-xwqc-g5wc) assessment: DoS-only, unreachable (we generate not parse specs),
correctly non-blocking; low-priority bump to 2.7.5 available.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 23:28:36 +02:00

11 KiB
Raw Blame History

ChicoryTV issue-queue handoff (living document)

Paste the prompt below into a fresh session to work the next item. Each session ends by UPDATING THIS FILE in place (rewrite the state section and the queue for the next item) so it always holds the current handoff. History: created 2026-07-02 after the plan audit (#59 epic); all backend gap issues (#100#111), all SPA screens (#84#89, #93, #109), the rebrand (#90), the cutover root-flip (#91 phase a), full scheduling parity (#144/#162), media/troubleshooting parity (#141/#161/#158/#180), onboarding docs (#185), the collections/API-gap batch (#155/#151/#152-backend/#184), and now the multi/rerun/playlist SPA editors (#151/#152 PR #194, #153 PR #195) + CI speedups (#190 PR #192) are MERGED. v26.5.0 in prod; v26.6.0 tagged (awaiting a Komodo pin bump 26.5.0→26.6.0 in server-management to deploy).

Blazor removal (#91 phase b) is now gated ONLY on #145 (playback troubleshooting) — every API gap (#151/#152/#153/#155) is closed.

Session state (2026-07-08, multi/rerun/playlist editors + CI/runner session): main = 81bcfec8. Merged THREE PRs (all fork-reviewed + live-E2E'd + CI-green before merge):

  • PR #192 → #190 CLOSED: CI speedups — NuGet package cache (actions/cache@v4 on ~/.nuget/packages) in the test+migrations jobs, shallow checkout for test (fetch-depth 1), and a Dockerfile openapi-generator jar-layer reorder. Validated on main's image build.
  • PR #194 → #151/#152 CLOSED: SPA multi-collection editor (/app/multi-collections) + rerun-collection editor (/app/rerun-collections), on the PR-#188 REST APIs. Mirror CollectionsScreen dialogs + a type→picker→playback-order machinery. Follow-up commit unions an out-of-set stored playback order into the rerun edit-load Select.
  • PR #195 → #153 CLOSED: playlist CRUD REST API (9 endpoints + RenamePlaylistGroup command + DTOs) and SPA editor (/app/playlists: group tree + item editor with reorder/copy + playout preview). Review hardening: HIGH — PUT /api/playlists/{id} now guards IsSystem→422 (a system playlist could be renamed/wiped via API); MEDIUMs — system-group rename guard + preview draft validation→422; SPA — Promise.allSettled on the tree load.
  • New issues filed: #193 (rerun create/update should existence-check selectedId — a bad id can dangling-FK/500; S, backend-only, still OPEN) and server-management#570 (relocate the Gitea act-runner off bumblebee — DONE by user, runner now on VM 127 on pve4).
  • Tests on main: ErsatzTV.Tests 913, web 369 (45 files), Core.Tests 493(+1 skip), Architecture 5 — all green (verified via the PR runs).

CI RUNNER (server-management#570 — RESOLVED 2026-07-08): the act-runner moved off bumblebee (where it starved Kodi/Jellyfin playback) to VM 127 on pve4 (ci-runner, 12 vCPU / 16 GB, shared ci-net, persistent /data/cache, capacity 2). An interim mis-config (6 vCPU + per-job networks that left the internal actions/cache server unreachable → a 15-min cache-save hang that killed run #363) was fixed. Verified fixed on run #371: the test-job log shows Cache restored from key: nuget-linux-… (732 MB) + Cache saved successfully (~1 s, no hang) + cache-hit→skip. Warm Build & test ~9 min (was 18m53s on the broken VM, ~45 min on bumblebee bare-metal — the ~2× is virtualization overhead, an accepted trade for off-prod isolation). Still true: a red MAIN push can be a CANCELLED job from VM churn (reboots) rather than a code fault — check the job conclusion (cancelled vs failed) and re-trigger via a workflow_dispatch re-run (Gitea 1.24 has no per-run rerun API) before assuming a regression. The non-blocking docs-reminder job runs on PRs only.

Lessons for all remaining prompts (conventions live in docs/; this is workflow lore):

  • READ docs/README.md → the convention docs FIRST; point recon/implementer agents at specific doc sections. The convention docs (api/spa/e2e/domain-model/blazor-route-parity) replace re-recon — only recon the task-specific delta (exact merged-API signatures, a Blazor page's field list) that docs deliberately don't freeze.
  • The main checkout (/Users/timothy/ersatztv) sits on a STALE branch. NEVER recon/edit there — worktrees off origin/main only; copy web/node_modules from the main checkout (cp -R) into NEW web worktrees instead of npm ci. Docs-only worktrees need none. Remove worktrees when the PR merges.
  • Subagent connection drops = the laptop slept, NOT a turn-length problem. The agent's context AND on-disk work survive. Re-resume with SendMessage ("you dropped when the laptop slept; git status shows X on disk; continue from step N"). This session recovered the #153 backend agent mid-task with zero lost work.
  • Build/verify locally, then trust it; CI is now the slow+flaky part (VM 127). Full local passes (dotnet test + web test/lint/build + check:api) + fork review + live-E2E gate a merge; the runner just confirms. Watch CI by commit status: /api/v1/repos/timothy/ersatztv/commits/{sha}/status (per-context state). Only Build & test (.NET) is branch-protection-required; the image build job is skipped on PR runs.
  • PR routine (works): worktree off origin/main → implement (opus for judgment-heavy, sonnet for mechanical; give doc pointers + exact facts; mandate the csharp-lsp for C#) → for API changes build the app project FIRST then ./scripts/update-openapi.sh (regens v1.json + endpoint-index) then npm run generate:api → merge origin/main into the branch before PR (resolve route-parity by hand; regen v1.json authoritatively) → full test pass → push, PR → fork adversarial review (SCOPE it "review only; do not answer unrelated questions") + sonnet live-E2E for UI changes (scripts/e2e-local.sh) → apply review should-fixes as follow-up COMMITS (never amend+force — auto-mode blocks the force-push) → CI green → merge (session pre-approval: RE-ASK each new session; this session the user OK'd auto-merge on CI-green + review-clean) → structured close comments per CLAUDE.md protocol.
  • Combine tightly-coupled API+SPA work (like #153) on ONE branch/PR to save CI cycles — extra relevant now that CI is slow. Do the backend first (it regenerates the TS types the SPA needs).
  • Never run TWO committing agents on the same worktree concurrently (races on git state). A read-only review fork alongside an editing agent is fine (the fork reads a committed SHA).
  • Reusable API facts: collection-item listings → reuse PagedLibraryBrowseItemsResponseModel + LibraryBrowseItemMapper; multi/rerun/playlist Application handlers ALL exist (API = controller +DTO+tests). Response DTO records need file-scoped #nullable enable; ErsatzTV.Application has NO nullable context (string? trips CS8632). LanguageExtensions.Apply collapses a NotFoundError subtype into a plain BaseError (→422) — use a controller existence pre-check for a real 404. The in-repo RerunCollectionsScreen is now the canonical mirror for a per-item CollectionType→picker→playback-order editor.

PROMPT — #145 playback troubleshooting (the LAST functional gate for #91 phase b)

You are Fable, the ORCHESTRATOR in the main Claude Code session (Claude Code only). Fable is EXPENSIVE: delegate (recon → Explore/haiku; mechanical/reconciles → sonnet; judgment-heavy code → opus; fable forks for review). FIRST read CLAUDE.md, docs/README.md + the convention docs it indexes, and the Lessons above.

HARD CONSTRAINTS:

  • Work in worktrees off origin/main; NEVER touch /Users/timothy/ersatztv (stale). Copy web/node_modules from the main checkout into NEW web worktrees.
  • Up to 3 concurrent builds OK; never 5+/wide fan-outs. NEVER set ETV_UPDATE_GOLDENS.
  • Subagent drops = laptop sleep; re-resume via SendMessage (work survives).
  • Merge consent in-conversation per session (last session's pre-approval does NOT carry over).
  • CI runner = VM 127 (server-management#570 RESOLVED — 12 vCPU, working actions/cache, ~9 min warm Build & test; verified on run #371). A red MAIN push is most likely a CANCELLED job from VM churn, not a code fault — check job conclusion (cancelled vs failed) + re-trigger via a workflow_dispatch re-run before assuming a regression. Apply review should-fixes as follow-up commits (no force-push).
  • Live-E2E new screens via scripts/e2e-local.sh (docs/e2e-local.md). Adversarial review fork per PR diff, SCOPED "review only". Update docs/blazor-route-parity.md rows in the same PR.

Task — #145 playback troubleshooting [L, OWN SESSION]

This is the last gate before #91 phase (b) (Blazor removal). It is LARGE and was deliberately deferred to its own session. The #91 issue body has the phase-(b) checklist.

  1. RECON [Explore, thorough]: map the legacy Blazor playback-troubleshooting UI (ErsatzTV/Pages/ — the FFmpeg/playback troubleshooting page(s), ffmpeg-troubleshooting report/download, session/HLS diagnostics) and what REST API exists vs is missing for it. Playback/session endpoints may be partial (see #99 TS/HLS-Direct sessions, still backlog). Product a mirror map: Blazor fields/actions → needed API → SPA screen.
  2. Decide the API gap: what troubleshooting/diagnostics endpoints must be added (mirror the controller+DTO+tests pattern; handlers may already exist) before the SPA screen.
  3. Implement backend (if needed) → SPA screen → live-E2E → full PR routine → close #145.
  4. Then #91 phase (b): with #145 done, plan/execute the Blazor removal (redirect remaining routes, delete legacy pages, update blazor-route-parity.md). This may itself be a separate session — scope it when #145 lands.
  5. Consider clearing #193 (rerun existence-check hardening, S backend) as a warm-up/interleave.
  6. Update THIS handoff, commit to main, print the next prompt in a fenced block.

Known facts (2026-07-08 — re-verify cheaply)

  • main = 4c58e19b (+ this doc commit); ErsatzTV.Tests 913 / web 369 / Core.Tests 493(+1) / Arch 5 all green. PR #196 (docs-first rule + docs-reminder CI job) merged.
  • v26.6.0 tagged (deploy = user bumps Komodo pin). CI runner = VM 127, retuned + verified stable (#570 resolved; ~9 min warm build).
  • Open follow-ups: #193 (rerun existence-check, S). #99 (TS/HLS-Direct sessions) still backlog — likely relevant to #145's diagnostics.
  • NU1903 Microsoft.OpenApi 2.0.0 (GHSA-v5pm-xwqc-g5wc) — a HIGH-CVSS advisory that appears as a build warning. Assessed 2026-07-08: DoS-only (stack overflow) reachable ONLY by parsing an untrusted OpenAPI doc with circular $refs; we only GENERATE our own spec (transitive via Microsoft.AspNetCore.OpenApi 10.0.2), so it's not reachable — correctly non-blocking under the #8 policy (Directory.Build.props exempts NU19011903; criticals/NU1904 still block). Fixed in Microsoft.OpenApi 2.7.5. LOW-PRIORITY hygiene: let Renovate bump it, or pin Microsoft.OpenApi 2.7.5 as a transitive override in Directory.Packages.props (SQLitePCLRaw precedent) + rebuild & confirm v1.json is byte-identical. Not urgent.
  • #91 phase (b) gated ONLY on #145 now.