Система публикаций obahoba — спецификация v1

Порядок, безопасность и находимость для 195 разбросанных публикаций. Всё крутится вокруг одного источника правды — реестра _published.json, который уже есть, но дырявый и не оживлён.

Твоё решение: инфру пока не трогаем
Твоё решение: авто-TTL, чистка позже
Твоё решение: хаб на корне под auth
Что показал аудит (факты):

1 · Ядро — реестр _published.json v2 единственный источник правды

Всё (хаб, безопасность, TTL) читает отсюда. Расширяем схему каждого артефакта — добавляем 5 полей к тому что есть:

{
  "url": "https://performante-ai.obahoba.com/kost.html",
  "type": "html|pdf|mp4|docx|site",     // что это
  "title": "...", "source_file": "...", "published_at": "...",
  "project": "performante-site",        // NEW — из какого конверта
  "audience": "public|client|internal", // NEW — кому можно видеть
  "lifecycle": "permanent|ephemeral",  // NEW — навсегда или одноразовое
  "expires_at": "2026-09-05",          // NEW — для ephemeral (published + TTL)
  "status": "live|archived"            // NEW — живой или уже убран
}

Категория (type) даёт фильтр «сайты · КП · презентации · видео · доки · отчёты». project — группировку. Остальное — безопасность и TTL.

2 · Хаб-«Диск» @ obahoba.com корень, под basic-auth

Генерируемая HTML-страница — твоя точка входа «найти актуальное». Читает ВСЕ _published.json проектов, рендерит каталог. Гейт на весь корень (он показывает всё → сам закрыт). Регенерация — на каждую публикацию (skill дописывает реестр → пересборка хаба) + ручная команда.

🔒 obahoba.com — Диск публикаций (basic-auth)
Все проекты
performante-site
youtube-factory
armpay
boreas
insta-blog
тип: все ▾аудитория: все ▾🔍 поисксорт: свежие ▾
CLIENT Performante — сайт-агентство · site
актуальное · 1д
CLIENT Performante КП Enterprise · pdf
INTERNAL BOREAS — отчёт по эджу · html
24д
PUBLIC ArmPay — сайт · site
постоянное
INTERNAL yt-niches ресёрч · html
⏳ истекает через 12д

Метка «актуальное» = свежайший артефакт своего типа в проекте. Ephemeral показывает возраст и «истекает через N». Клик → сама ссылка.

3 · Классификация + безопасность спроектировано — применяется по твоему «да», инфру сейчас не трогаю

Три тира аудитории → три политики в Caddy. Дефолт для НОВОЙ публикации — определяется по контексту (lab/ресёрч/гейт = ephemeral+internal; клиентская сдача = client; маркетинг-сайт = public), с возможностью переопределить.

ТирЧто этоИндексацияЛистинг папкиДоступ
PUBLICМаркетинг-сайты, портфолиоможнонет (нормальный индекс)открыто
CLIENTКП, сдачи, демо клиентуnoindexнетнеугадываемый путь / гейт по желанию
INTERNALОтчёты, ресёрч, трейдинг, гейтыnoindexнетbasic-auth

Ключевой фикс: голый file_server browse (28 доменов сейчас перечислимы) заменяется на генерируемый пер-проектный индекс — тот же движок, что и хаб, но с тиром доступа. Enumerable-дыра закрывается по дизайну.

4 · Время жизни (TTL) механизм сейчас — массовая чистка позже

5 · Что делаем сейчас vs потом

▸ Сейчас (без инфры — только файлы)

  • Схема _published.json v2 + бэкфилл ~28 неучтённых и полей аудитории/lifecycle к 167 существующим.
  • Генератор хаба (читает все реестры → HTML-«Диск»).
  • TTL-механизм: проставление expires_at + джоба-архиватор (пишет в реестр, домены НЕ трогает).
  • Правка skill obahoba-publish: спрашивать/выводить тир + lifecycle, дописывать новые поля, дёргать пересборку хаба.

▸ Потом (по твоему «да» — инфра)

  • Поднять корень obahoba.com + basic-auth, задеплоить хаб.
  • Применить security-тиры в Caddy (noindex, гейты, замена browse).
  • Массовая ретро-чистка 195 субдоменов по классификации.

6 · Открытые параметры

TTL по умолчанию для ephemeral: предлагаю 60 дней. Ок / другое?
Бэкфилл аудитории 167 артефактов: эвристикой по имени проекта (armpay/performante→client, trading/research→internal, лендинги→public) с твоей вычиткой сомнительных — или размечаешь сам?
Креды basic-auth хаба: генерю логин/пароль, кладу в .vault/ — на этапе «потом».
Спека дизайн-стадии, инфра не тронута. Скажешь «делай Сейчас» (+ ответы по параметрам) — начну с реестра v2 + бэкфилла + генератора хаба, всё в файлах, домены не трогаю до отдельного «да» на инфру.