Ассерт `/api/v1/me → 401` проходил в обоих мирах: если monkeypatch
auth_mode тихо не подействует, запрос без заголовка уходит в ветку «нет
заголовка» и даёт тот же 401 (и тот же 404 на admin-пути). Теперь
сверяется detail РАВЕНСТВОМ со строкой db_only-ветки; `in` не годится —
'valid session required' является подстрокой dual-текста.
Мутация (monkeypatch режима закомментирован) даёт красный:
assert 'no authenticated user (valid session required)' == 'valid session required'
#3360. Периметр /trade-in/api/v1/admin/* снаружи не срезан (caddy/sites/apps.caddy:
блок `handle /trade-in/api/*` стоит выше `import caddy/users.caddy.snippet`), и
срезать его нельзя: admin-UI кабинета зовёт эти пути ИЗ БРАУЗЕРА (12 файлов
tradein-mvp/frontend/src — scrapers/**, components/scrapers/**, admin-audit-api.ts,
GuardedRoute). Значит внешний аноним доходит до rbac_guard, а после #3324
(несуществующий путь → 404 роутера) 401 на существующей ручке стал оракулом:
перебором имён восстанавливался список admin-API.
Все три ветки «личность не установлена» (нет X-Authenticated-User, auth_mode=db_only,
подделанный заголовок без #2213-секрета) на admin-префиксе теперь отдают ровно то же,
что роутер даёт на несуществующий путь. Аутентифицированные не тронуты: admin — 200,
не-admin — 403 «admin only» (прятать наличие ручки от опознанного человека незачем).
Смоук периметра: пара admin-путей — существующий /admin/proxies и несуществующий
/admin/users — оба обязаны быть 404 снаружи.