# docs/ — task-signal map Purpose: route a fresh contributor/agent to the minimal set of docs for the task at hand, instead of a mandatory front-to-back read. **Update this doc in the same PR that adds, removes, or retitles a doc below, or that changes which sections a task signal points to.** ## Start here, always - **`CLAUDE.md`** (repo root) — project intro: architecture, layout, dev commands, conventions, Task Completion Protocol. - **`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. ## Task signal → minimal sections | Signal | Read | | --- | --- | | Session startup / "what's next" (no issue named) | `docs/handoffs/chicorytv-issue-queue.md` (standing kickoff — two concurrent tracks: orientation ‖ `scripts/select-queue.sh 5`) | | Named-issue pickup | Skip queue selection; go straight to focused retrieval — see "Knowledge retrieval" below, then the issue body | | Adding/changing a `/api/*` endpoint | `docs/api-conventions.md` checklist + `docs/endpoint-index.md` | | Adding a ChicoryTV SPA screen | `docs/spa-conventions.md` | | Scheduling / playout engine work | `docs/domain-model.md` + decisions catalog rows keyed `sched.*` (`docs/decisions/README.md`) | | Concurrency / optimistic-locking work | `docs/api-conventions.md` §7a/b/c + `docs/decisions/optimistic-concurrency.md` | | Auth / security-surface work | `docs/decisions/api-auth-security.md` | | CI / release pipeline work | `docs/ci-cd.md` + `docs/decisions/release-ci-governance.md` | | Live local run / Playwright-MCP verification | `docs/e2e-local.md` + `scripts/e2e-local.sh` | | What does a test suite cover | `docs/testing.md` | | Legacy Blazor route lookup | `docs/blazor-route-parity.md` (historical #91 phase (b) inventory) | | "Why do we do X this way" / challenging a convention | **Catalog-first**: `docs/decisions/README.md` (active rows) → `docs/decisions.md` + `docs/decisions/*.md` for full rationale. `docs/decisions/archive/` only for "what did the rule used to be." | ## Knowledge retrieval (MemPalace + catalog + Gitea) These four rules are the seam agreed with server-management#642 (the Gitea→MemPalace exporter). They apply whether the question comes up via MemPalace, a grep, or a stale comment: 1. **Current conventions/decisions → catalog-first.** Start at `docs/decisions/README.md`; discover via the `ErsatzTV-Decisions` wing (active) / `ErsatzTV-Decisions-Archive` (superseded/retired). **Resolve by topic/key, never by chasing a file path.** 2. **Issue history → evidence, not authority.** The `Gitea-ErsatzTV` wing is historical narrative that may be stale; it never overrides current Markdown. 3. **The breadcrumb rule (the crux behavior change).** A file path named inside a *historical issue comment* (e.g. "grep `docs/decisions.md` 2026-07-17", "see …") is a **breadcrumb, not a live pointer.** Find the current rule via the catalog / active wing **by concept**; do not treat the named path as current. (Why it's safe: still-current → in the active wing, breadcrumb resolves; superseded → the active wing returns the *successor* and a literal follow lands on a record that announces its own `status: superseded`; retired → the active wing returns nothing, which is itself the signal. The validator-enforced move-to-`archive/` is what prevents the catastrophic "superseded rule read as current" case.) 4. **Fallback when MemPalace is stale/down:** `docs/decisions/README.md` catalog, then `` rg '^`key: `' docs/decisions/ ``. MemPalace is never authority nor sole fallback. MemPalace is candidate discovery only — every passage is verified against its cited Markdown/Gitea source before use. Never derive live queue state from MemPalace, #237, or historical comments; queue state is live Gitea state, retrieved via `scripts/select-queue.sh` (see `docs/handoffs/chicorytv-issue-queue.md`). Full retrieval contract (altitude/precedence, staleness bounds, what's mined per issue): `docs/handoffs/chicorytv-issue-queue.md` → "Knowledge retrieval". ## Also present in `docs/` - **`docs/domain-model.md`** — what the app IS: entity glossary, channel→playout→schedule/block concept map, where each concept is edited in the SPA. - **`docs/api-conventions.md`** — checklist for adding/changing a `/api/*` endpoint (controllers, DTOs, error mapping, auth, OpenAPI regen, tests). - **`docs/spa-conventions.md`** — playbook for adding a screen to the ChicoryTV React SPA. - **`docs/e2e-local.md`** (+ `scripts/e2e-local.sh`) — how to run a live local instance for manual or Playwright-MCP verification. - **`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. - **`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. - **`docs/decisions.md`** + **`docs/decisions/*.md`** — active decision records (lifecycle schema: key/status/since/supersedes/superseded-by). **Generated active view**: `docs/decisions/README.md` (catalog / task router) — start there. Superseded/retired records live in `docs/decisions/archive/` and are read only for history, never for "what is the current rule." - **`docs/ci-cd.md`** — build/test/release pipeline, versioning, dependency management. - **`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/mcp.md`** — the `ErsatzTV.Mcp` stdio JSON-RPC MCP server (#58): how it wraps `/api/v1` as read + cautious-write tools, its config/env vars, auth, security posture, and the tool catalog. - **`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 is **live Gitea state**, retrieved each session via `scripts/select-queue.sh` — see that file's standing kickoff for the two concurrent tracks (orientation ‖ selection). ersatztv#237 is a closed, archival historical tracker (superseded by `startup.parallel-orientation` in `docs/decisions.md`) — not a live pointer. - **`docs/tracker-retrofit-triage-237.md`** — audit trail for the #524 triage of ersatztv#237's 111 comments (method, per-comment classification, totals). Evidence for the `docs.tracker-comment-retrofit` decision; read it only when triaging another over-cap tracker. - **`docs/handoffs/rest-api.md`** — original handoff prompt for kicking off the REST API work (#2).