- беклог и план переехали в docs/tasks (38 задач, 11 целей), слаги переименованы с транслита на английские, 85 ссылок поправлены - conventions.md разобран в docs/conventions/, local-research.md — в docs/research/, review-journal.md — в docs/review.md с разделом настройки конвейера; заведены security.md, adr/ и .pm.json - шаг docs.py check добавлен в task gate; поведение в architecture.md помечено девятью маркерами долга, database.md получил настройки с числовым значением
3.6 KiB
Заголовки доставки в архиве рядом с телом
Секция: ядро · Хук: Заголовки живут только в базе — потеря базы навсегда ломает вывод слоя при пересборке · Теги: goal:journal-and-rebuild
Состояние объявлено свёрткой по журналу, а журналом — сырой архив. Но в архиве
лежит только тело: заголовки запроса (automation-id,
automation-aggregation, Accept-Language и всё незадокументированное) живут
единственной копией — в колонке delivery.headers.
Отсюда дыра, которую пересборка обнажила, а не создала. healthlog reindex
читает учёт из рабочей базы именно потому, что восстановить заголовки неоткуда.
Пока база цела, это работает. Если базу потерять, весь журнал становится
«телами без учётной записи»: automation-id пуст, наследовать слой не от чего,
заголовок не подтверждает ничего — и доставки без плотных метрик не сохранятся
никогда, сколько ни пересобирай. То есть «пересобираемо из архива» верно с
оговоркой, которой в инварианте нет.
Prior art прямой: WARC (формат веб-архивов) хранит запрос вместе с его заголовками именно потому, что тело без метаданных запроса события не воспроизводит. Смотреть у него стоит на устройство записи «заголовки + тело» и на то, что заголовки лежат рядом текстом, а не в отдельной базе.
Развилка формы (решать при взятии, не сейчас):
- заголовки внутрь того же
.json.gzотдельным первым объектом — одна запись и одна операция, но файл перестаёт быть «телом как пришло»; - файл-спутник
<ulid>.headers.json— тело остаётся дословным, зато на доставку два файла и два fsync, а атомарность пары надо обеспечивать самому; - отдельный журнал заголовков (файл на сутки, дописыванием) — дешевле всего по операциям, но появляется третья сущность.
Цена ошибки высокая: правится путь приёма, а доставка, не попавшая в архив,
теряется навсегда. Значит профиль ревью — deep, и менять надо так, чтобы
старые тела без заголовков продолжали читаться.
Готово, когда пересборка на архиве, у которого рабочей базы нет вовсе, даёт то же состояние, что пересборка с базой.
Связано: docs/architecture.md → «Сырой архив и восстановление состояния»,
internal/replay.