## 1. Экспортируемое слоистое разрешение (naming)

- [x] 1.1 `internal/naming`: тип `LabelFields` (Title/Director/Year/Season string)
  с методом `Label()`, зовущим существующий `Label(...)`
- [x] 1.2 `internal/naming`: функция `EffectiveFields(parsedContext string, plan
  recognize.Plan) LabelFields` — перенести логику слоёв из
  `worker.effectiveDisplayName` (план → контекст; сводка сезонов плана →
  контекстный `SeasonLabel`); выбор слоя по сырым значениям, выбранные скаляры
  на возврате прогнать через `sanitize` (идемпотентно — `Label()` даёт прежний
  результат); битый `parsed_context` → пустой слой
- [x] 1.3 Юнит-тесты `naming.EffectiveFields`: режиссёр/год/сезон из плана;
  фолбэк на контекст; матч бьёт контекст; битый `parsed_context`; пустые
  значения; режиссёр из управляющих символов/лишних пробелов → `.Director`
  очищен и `.Label()` совпадает с прежним `display_name`

## 2. Переиспользование (worker)

- [x] 2.1 `worker.effectiveDisplayName` → тонкая обёртка
  `naming.EffectiveFields(d.ParsedContext, plan).Label()`; поведение и тесты
  `displayname_test.go` не меняются

## 3. Вывод режиссёра в вью (httpapi)

- [x] 3.1 `download.go`: поле `downloadDetailView.Director`; в `buildDownloadView`
  заполнить из `naming.EffectiveFields(d.ParsedContext, rd.Plan).Director`
- [x] 3.2 `review.go`: `view.Director` из `naming.EffectiveFields(rd.Download.
  ParsedContext, rd.Plan).Director` вместо `rd.Plan.Director`
- [x] 3.3 `web/templates/partials/download_main.html`: поле «Режиссёр» —
  `{{if .Director}}…{{else}}<span class="faint">—</span>{{end}}` вместо прочерка

## 4. Проверки и закрытие

- [x] 4.1 (опц.) httpapi-тест: режиссёр присутствует во вью страницы загрузки,
  если инфраструктура тестов позволяет
- [x] 4.2 `task test` и `task lint` зелёные; `openspec validate --strict`
- [x] 4.3 Удалить `docs/tasks/items/rezhisser-v-kartochke-zagruzki.md` и строку в
  индексе беклога `docs/tasks/BACKLOG.md`
