Files
ersatztv/docs/handoffs/chicorytv-issue-queue.md
T
timothyandClaude Fable 5 dfd2134cb4
Build ErsatzTV Image / Build & test (.NET) (push) Has been cancelled
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Has been cancelled
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
Build ErsatzTV Image / Docs update reminder (push) Has been cancelled
docs: queue protocol v2 — state moves to pinned Gitea tracker #237 (parallel-session safe)
Handoff file reduced to static kickoff prompt + append-only lessons lore;
queue/arc/session log live in pinned tracker ersatztv#237 with in-progress
claim labels and end-of-session triage. Decision recorded in decisions.md;
docs index updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 01:17:26 +02:00

7.2 KiB
Raw Blame History

ChicoryTV issue-queue handoff (static kickoff + workflow lore)

PROTOCOL CHANGED 2026-07-11 (decisions.md entry of same date). Queue state lives in the pinned Gitea tracker ersatztv#237, not in this file. Do NOT write session state, queue order, or next-session prompts here — sessions ending under the old protocol should append their session comment to #237 instead. This file holds only the two stable things: the standing kickoff prompt and the workflow lore. Historical per-session state: git log of this file (last state-bearing revision: 8b77d5e7).


STANDING KICKOFF PROMPT (paste into a fresh session, unchanged every time)

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

Then work the queue:

  1. Read the pinned tracker ersatztv#237 — body = goal + ordered arc + session protocol — and its most recent session comments; list open issues in the Blazor removal (#91 phase b) milestone and with the review label.
  2. Pick the top arc item that is open and NOT labeled in-progress (or the item the user names).
  3. Claim it: add the in-progress label + a "claiming" comment on the issue(s).
  4. Read the issue bodies (they carry the task context/evidence) and work the item under the HARD CONSTRAINTS below.
  5. Finish by following the session-end protocol in #237: ONE session comment on the tracker (template in the tracker body, incl. triage verdicts for any new issues), remove your in-progress labels, and complete the per-issue Task Completion Protocol from CLAUDE.md.

HARD CONSTRAINTS:

  • Work in worktrees off origin/main. Copy web/node_modules from the main checkout.
  • PARALLELIZE BY DEFAULT: split the task into disjoint slices up front and run 34 implementer agents concurrently (recon agents are free — always fan those out). 34 concurrent dotnet/npm builds are fine on this Mac (M4, 10 cores, 16 GB); check uptime before a big fan-out — if 1-min load > ~6, drop to 23. Never 5+ builds (the historic crash was an 89-way fan-out). NEVER set ETV_UPDATE_GOLDENS.
  • Never two committing agents on ONE worktree — give each parallel slice its own worktree branched off the feature branch and merge back. Sequence only where a slice genuinely depends on another's output (backend-first narrow, SPA-wide after worked well for #216).
  • Merge consent in-conversation per session (prior pre-approvals do NOT carry over).
  • Arm a CI monitor on the PR head sha AT PR-OPEN (commit-status endpoint), not at the end.
  • Live-E2E via scripts/e2e-local.sh; NEVER exercise download endpoints via browser tabs (curl them). Adversarial review fork per PR diff, SCOPED "review only".

Lessons / workflow lore (append-only; conventions live in docs/, this is workflow lore)

  • READ docs/README.md → the convention docs FIRST; point recon/implementer agents at specific doc sections. Only recon the task-specific delta.
  • blazor-route-parity.md carries mutation-depth verdicts (2026-07-09 sweep table at the top of Section 2). A row is only trustworthy if its cluster verdict is PARITY-OK; the sweep evidence lives in the issues #207#213. Keep the verdict table updated as gates close.
  • "Screen exists" ≠ parity: the root cause of the false SPA-READY rows was same-session verification that never diffed capabilities against the Blazor page. Per-capability diff vs the Blazor page is the standard for any future parity claim.
  • Several gaps are UNWIRED EXISTING endpoints (playout delete/reset, block copy, scan-show, collections add-item kinds) — check the endpoint index before building new API surface.
  • Keep the MAIN checkout's web/node_modules fresh (npm install after pulling a PR that adds a dep) — worktrees copy it, and a stale copy broke typecheck in a #198 worktree.
  • Playwright-MCP E2E: never open tabs/window.open for file-download endpoints — curl them. If browser tools stall repeatedly, pkill -f ms-playwright-mcp and drive a fresh session.
  • The user's main checkout (/Users/timothy/ersatztv) stays ON main and pulled each session. Feature work in worktrees off origin/main; copy web/node_modules from the main checkout.
  • Subagent connection drops = laptop sleep/transient; re-resume via SendMessage (work survives).
  • Build/verify locally, then trust it; CI (VM 127) confirms (~9 min warm). Watch by commit status: /api/v1/repos/timothy/ersatztv/commits/{sha}/status.
  • PR routine (works): worktree off origin/main → implement (opus judgment-heavy / sonnet mechanical; doc pointers + exact facts; csharp-lsp for C#) → API changes: build app project FIRST then ./scripts/update-openapi.sh then npm run generate:api → full local test pass → push, PR → fork adversarial review (SCOPED "review only") + live-E2E for UI changes (scripts/e2e-local.sh) → review fixes as follow-up COMMITS (never amend/force-push) → CI green → merge (consent per session) → structured close comments per CLAUDE.md protocol.
  • Never run TWO committing agents on one worktree concurrently. Read-only review forks are fine.
  • Reusable API facts: DTO records in ErsatzTV.Core/Api need file-scoped #nullable enable; ErsatzTV.Application has NO nullable context (CS8632); Option<T>→nullable = MatchUnsafe(v => (T?)v, () => null); LanguageExtensions.Apply collapses NotFoundError→422, so real 404s need a controller pre-check; id-taking child GETs get an OpenApiErrorResponseContractTests [TestCase].
  • Arm a CI monitor the moment the PR opens — in the #216 session three PR runs sat red for ~an hour (a CI-only debounce-timing flake) while review/E2E ran, because CI was only checked "at the end". Also: concurrent runs can collide on the MySQL service host port 3306 ("port is already allocated") — that's infra flake, rerun; consider unpinning the host port.
  • "Make X consistent with Y" review findings deserve new-code scrutiny — a #216 review fix propagated MediaBrowseScreen's mount-debounce selection-wipe race to SearchScreen instead of catching it. For any timer/effect, ask "when does this fire?" (incl. mount).
  • SPA mutation affordances on media items: USE the shared web/src/media/addTo/ layer (spa-conventions §5c) — don't build screen-local pickers. Schedule adds are valid only for shows/seasons/artists (server validator).
  • Live E2E seeding: the local library isn't API-seedable; the #216 E2E agent generated tiny ffmpeg testsrc MKVs + inserted LibraryPath rows via SQL then scanned. Recipe not yet in docs/e2e-local.md — worth adding next time it's needed.
  • Parallel sessions (2026-07-11 protocol): claim before working (in-progress label — the tiny read→claim race window is accepted; later claimant backs off). Claiming prevents duplicate pickup, NOT overlapping code changes — check the tracker's dependency notes ("#234 after #231", "coordinate with #215") before touching shared surfaces. Lessons edits to THIS file: append bullets only, git pull --rebase before commit.