## Why

Сервис отдаёт данные, но человеку их показать нечем: экранов нет вовсе, а
браузер, открывший адрес сервиса, получает поверхность хранилища вместо
приложения. Два основных сценария паспорта — «семейный архив» и «возвращение к
записи» — не работают ни один, и упираются они в одно: приложения не существует.

Каркас сам по себе экранов не приносит. Он приносит то, на чём они стоят:
собранное приложение, которое сервис отдаёт браузером, открывается по любому
своему адресу и показывает вошедшего, спросив об этом сервис.

## What Changes

- Сервис начинает отдавать браузеру **приложение**: разметку и её ресурсы. Они
  лежат внутри самого бинарника, отдельного каталога рядом с ним не требуется, и
  внешнего веб-сервера под них не заводится.
- Неизвестный адрес **вне корней сервиса** отдаёт разметку приложения, а не
  отказ. Так обновление страницы посреди приложения открывает тот же экран, а не
  ошибку. Корни перечислены поимённо, и адрес **внутри** корня в приложение не
  проваливается никогда: отказ контракта остаётся отказом контракта.
- Разметка и её ресурсы отдаются **без сессии**: приложение само спрашивает
  сервис, кто вошёл, и уводит ко входу, когда не вошёл никто. Требование сессии
  на самой разметке отдавало бы отказ вместо экрана входа.
- Открытое приложение показывает **вошедшего** — то, что сервис ответил о нём, —
  и это единственное, что оно сегодня показывает.
- В сборку приходит **шаг сборки приложения**: он входит в набор проверок и в
  сборку образа. Спеками это не нормируется — у сборки другой потребитель, тот,
  кто собирает.

## Capabilities

### New Capabilities
- `webapp`: приложение в браузере — чем сервис его отдаёт, каким адресом оно
  открывается, что делает обновление страницы посреди приложения и что человек
  видит, открыв его.

### Modified Capabilities
- `access`: разметка приложения и её ресурсы пополняют перечень адресов,
  открытых без сессии; сегодня в нём только проба здоровья и метрики.

## Impact

- новый каталог приложения: исходники, зависимости, настройка сборки;
- `internal/controller/http` — маршрут, отдающий разметку на неизвестном пути вне
  корней, и раздача ресурсов приложения из бинарника;
- `Taskfile.yml` — шаг сборки приложения, его место в наборе проверок и в сборке
  образа;
- `Dockerfile` — приложение собирается внутри образа, чтобы выкладка не зависела
  от машины разработчика;
- `.gitignore` — каталог зависимостей и собранное приложение;
- новая внешняя зависимость сборки: Node и его установщик пакетов. На машину
  разработчика они не ставятся — шаг сборки зовёт их контейнером, поэтому
  требованием к машине становится docker, которым и так собирается образ;
- `docs/conventions/web-ui.md` и `docs/architecture.md` — правила кода
  приложения перестают быть выведенными из выбора, а компонент и зависимость
  сборки появляются в описании устройства.
