Build ErsatzTV Image / Docs update reminder (push) Has been skipped
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m19s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 8m34s
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
123 lines
9.3 KiB
Markdown
123 lines
9.3 KiB
Markdown
# 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](http://192.168.1.95:3000/timothy/ersatztv/issues/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; ALSO list open `ersatztv`-labeled issues in
|
||
**timothy/adversarial-reviewer** — unclaimed audits there are pickup candidates too
|
||
(read-only, parallel-safe; see the tracker's "Pending adversarial reviews" section).
|
||
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);
|
||
reviewer-repo audits are claimed by comment only.
|
||
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 3–4 implementer
|
||
agents concurrently (recon agents are free — always fan those out). 3–4 concurrent
|
||
dotnet/npm builds are fine on this Mac (M4, 10 cores, 16 GB); the go/no-go signal is FREE
|
||
RAM, not CPU load (`memory_pressure -Q`: <20% free → don't launch more build agents; <10% →
|
||
pause/stagger). CPU load spikes during builds are benign. Never 5+ builds (the historic
|
||
crash was RAM starvation from an 8–9-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.
|
||
- **Fan-out health = RAM, not CPU load** (2026-07-11, user calibration): the 8–9-way crash was
|
||
RAM starvation. `uptime` load of 10–24 during parallel Roslyn/vitest bursts is benign with
|
||
memory healthy. Watchdog pattern: background monitor emitting only when `memory_pressure -Q`
|
||
free % < 20 (silence = healthy); pause/stagger agents below 10%.
|
||
- **CI MySQL host-port collision FIXED on main** (`ef8915f1`, issue #236): the migrations
|
||
service no longer publishes host 3306. Branches created before that commit still collide —
|
||
merge main in. There are now TWO runners (ci-runner VM 127 + bumblebee-runner), 4 slots:
|
||
faster drains, and superseded-run results are ignorable. Neither the cancel-run API route
|
||
nor the web cancel route exists on this Gitea version — stale runs just drain.
|
||
- **Two sessions touching one machine**: a branch may be checked out in ANOTHER session's
|
||
worktree — never commit/merge inside a worktree you didn't create. To land a merge on such a
|
||
branch without touching their checkout: plumbing merge (`git read-tree -m base ours theirs`
|
||
into a temp GIT_INDEX_FILE → `write-tree` → `commit-tree -p ours -p theirs` → push the
|
||
commit to the branch ref); the owning session then `git pull`s.
|
||
- **Codex is back in the review rotation** (2026-07-11): the 2026-07-06 "retired — usage
|
||
exhausted" was a quota window, not retirement. Codex has 5-hourly + weekly limits (same
|
||
structure as Claude); rule: **if we have usage, use it** — for INDEPENDENT review passes
|
||
(per-PR adversarial review alongside the fork review, adversarial-reviewer audits/re-reviews,
|
||
stuck-diagnosis second opinions) via `codex:rescue`, never for implementation. Check
|
||
readiness/quota with `/codex:setup`; on exhaustion fall back to fork/subagent review and
|
||
retry next window.
|