Files
ersatztv/docs
timothy fe6e2722f8
Build ErsatzTV Image / CI image pin matches docker/ci (pull_request) Successful in 6s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 5s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 4s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m1s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 19s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 16s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m54s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 14m5s
docs(lore): batching, no "main checkout", trust the queue, killed≠failed
Operator-requested after PR #405 pushed 5 times, orphaning live runs the
operator had to cancel by hand. Batches every standing-lore correction this
session produced into one commit (per the batching rule it adds).

New HARD CONSTRAINTS:
- BATCH PUSHES. Cancellation is impossible from the agent side on Gitea 1.25.4
  — REST .../runs/{id}/cancel and MCP cancel_run both 404, and the web-UI route
  needs a session+CSRF that doesn't script. Only the operator can cancel, so an
  orphaned run holds a runner slot until it finishes. If you must supersede a
  live run, SAY SO.
- TRUST THE GITEA BUILD QUEUE. Do not gate/throttle a push on host health; the
  runners were retuned for stability. Batch because you can't cancel what you
  orphan, not to protect the host.
- BOM-CHECK touched .cs before pushing. The #311 gate is fix-as-you-touch, and
  it bit two sessions the same day (PR #405 ×6; #70/PR #402 ×19 via Python
  utf-8-sig writing BOMs back). Verify your detector — an od-based grep reported
  all-clean while 19 files were dirty.
  Corrects a claim I nearly published: `dotnet format --include` DOES work here.
  The apparent no-op was the SHELL — CI's mapfile is bash-only, zsh has no
  mapfile → empty array → zero files → exit 0. Run it under bash -c.

THERE IS NO "main checkout" — the biggest correction here.
/Users/timothy/ersatztv is a shared mutable working tree whose HEAD is whatever
the last session left there. Its name lies, and it bit TWO sessions on
2026-07-17, both doing the obvious thing: one assumed main and committed onto
the #604/CI session's branch 24s after that session's own commit; another read
git log there and concluded main was "4 behind origin" — a phantom. Framed as a
design flaw, not a discipline failure: "check git status first" appears to
confirm the false assumption and then goes stale (it WAS on main at 12:46 and
wasn't by 14:17). Worktree discipline itself is healthy — 10 feature worktrees.

Diagnosing CI reds — three ways to misread one, all hit this session:
- A KILLED job reports conclusion=failure, not cancelled. The tell is a log that
  stops mid-step with NO error and NO failure marker. A runner retune killed run
  1006's migration + E2E on a BOM-only diff that couldn't break them. Log
  timestamps are UTC, host is UTC+2 — convert before correlating.
- cancelled ≠ failure: a cancel is NO verdict, and a run marked failure may hold
  a genuine job failure from BEFORE the cancel. Monitors must count FAILED and
  CANCELLED separately.
- "Unable to pull refs/heads/v4" is act refreshing its action cache and is
  followed by "Cloned …" — noise, not a cause. Grep the failure marker, not
  the word "error". An infra-shaped red (setup/cache step, before your code
  compiles) is not a code failure; don't file a CI bug off one sample.

Also: the cheap selector's failure modes are wider than deps+priority — it also
misses in-progress claim state and umbrella-vs-child.

Docs-only.
2026-07-17 18:15:32 +02:00
..

docs/ — reading order

Purpose: index of docs/ so a fresh contributor/agent knows what to read and in what order. Update this doc in the same PR that adds, removes, or retitles a doc below.

Read in this order at session start:

  1. CLAUDE.md (repo root) — project intro: architecture, layout, dev commands, conventions.
  2. docs/contributing.md — established code patterns (CQRS/MediatR, LanguageExt, the ChicoryTV SPA, EF Core dual-provider migrations, FFmpeg pipeline, analyzers, testing). Read before any non-trivial change.
  3. docs/domain-model.md — what the app IS: entity glossary, channel→playout→schedule/block concept map, where each concept is edited in the SPA.
  4. docs/api-conventions.md — checklist for adding/changing a /api/* endpoint (controllers, DTOs, error mapping, auth, OpenAPI regen, tests).
  5. docs/spa-conventions.md — playbook for adding a screen to the ChicoryTV React SPA.
  6. docs/e2e-local.md (+ scripts/e2e-local.sh) — how to run a live local instance for manual or Playwright-MCP verification.
  7. docs/testing.md — testing map: what each *.Tests project / web suite covers, golden-file nets, the timezone-independence rule, how to run subsets, the per-PR verification gate.
  8. docs/blazor-route-parity.md — historical record of the completed #91 phase (b) cutover: the Blazor Server UI is removed and every legacy route now 302-redirects to its SPA equivalent (or falls through to the catch-all → /app). Read it for the full legacy→SPA route inventory.
  9. docs/decisions.md — append-only "why" log. Check here before challenging an existing convention. Start from its Index, which links the four topic files under docs/decisions/ (large same-topic clusters) and lists the remaining in-file entries.
  10. docs/ci-cd.md — build/test/release pipeline, versioning, dependency management.

Also present in docs/:

  • docs/rest-api.md — REST API design doc for ersatztv#2 (goals, conventions, per-slice plan). Largely superseded day-to-day by docs/api-conventions.md; read this for the original rationale.
  • docs/channels.md — Channel entity field reference.
  • docs/m3u-xmltv.md — M3U/XMLTV generation overview (ChannelPlaylist, GetChannelGuideHandler).
  • docs/fork-strategy.md — divergence policy vs upstream ErsatzTV.
  • docs/design-sync.md — Claude Design ↔ repo screen workflow (#92).
  • docs/endpoint-index.md — generated REST endpoint index (method/path/operationId/summary per OpenAPI tag). Do not edit by hand; regenerated by scripts/generate-endpoint-index.py / scripts/update-openapi.sh.
  • docs/handoffs/chicorytv-issue-queue.md — static session kickoff prompt + workflow lore. Queue state (goal, arc, what's in flight/next) lives in the pinned Gitea tracker ersatztv#237 — read that, not this file, for current state (protocol: decisions.md 2026-07-11).
  • docs/handoffs/rest-api.md — original handoff prompt for kicking off the REST API work (#2).