docs(glossary): четыре термина переименованы, world.md и stand.md вычитаны

- Зачем:
  - справочники читает человек со стороны, а «пульт мира», «опись мира»,
    «работник» и «сырьё» звучали шуткой или калькой времён разработки
    (тикет #214, выбор владельца).
- Что:
  - CONTEXT.md: статьи «Паспорт мира», «Даги модельного времени»,
    «Шаговый даг», «Сырые данные», старые слова в строках «Избегать»;
    пометки в ADR 0005, 0008, 0009 без переписывания решений.
  - замены по README, справочникам, путеводителю, лабам, спекам,
    комментариям дагов и SQL, тегу дага и панели Grafana; имена в коде
    не тронуты.
  - world.md и stand.md: 35 находок вычитки внесены, регистр выровнен.
- Проверка:
  - make config-test; make lint в корне и в generator/; make test в
    generator/ (437 passed); скрипт ссылок из #212 пуст; grep старых
    слов вне ADR, research и CONTEXT.md пуст.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QBCtU38qSHg5DvgtnKXcW
This commit is contained in:
ddadminandClaude Fable 5.1 committed 2026-09-02 16:46:50 +03:00
1 parent 86ad8afaf2
commit 59d8c83b17
54 files changed
+794 -776

No files matched your search

+3 -3
View File
@@ -30,9 +30,9 @@
`ORDERS` для заказной стороны и `BEACONS` для событийной; броски независимы,
пересечения выходят арифметикой, приоритет классов работает по-настоящему —
[классы расхождений и опоздание](fate.md).
- **Опись хранит только то, чего движение мира не меняет**: хеш байтов
каждого слепка и счётчики наблюдаемых классов —
[что хранит опись](inventory.md).
- **Паспорт хранит только то, чего движение мира не меняет**: хеш байтов
каждого слепка и счётчики наблюдаемых классов — [что хранит
паспорт](inventory.md).
- **Мост к склейке**: план состава владеет человеком; его непрозрачный
`person_id` заказ показывает как `user_id`, кликстрим остаётся анонимным —
[мост к склейке](identity.md).
+20 -21
View File
@@ -8,18 +8,18 @@
**Рамка.** Расхождение — не грязь и не шум, а часть мира: судьба заказа,
решённая при его рождении и уложенная в окно K целиком.
**Два подпотока дня.** Заказная сторона — судьба заказа: исход, моменты,
дельта, опоздание. Событийная сторона — порча событийного потока: потеря и
дубль. Довод за разделение — различимость по описи: правка заказной механики
не двигает хеши событий, правка событийной не двигает байты слепка, и по
покрасневшим хешам видно, какую сторону трогали. Прежние имена `DISCREPANCIES`
и `LATECOMERS` решения не переживают — они названы по классам витрины, а
компонент называет часть мира; новые стороны занимают те же позиции.
Заказная сторона названа при реализации — подпоток `ORDERS` на позиции 2;
событийная — `BEACONS` на позиции 3: маячок счетчика либо не долетает, либо
отправляется повторно. Отклонено: *один компонент на всю судьбу* — правка
событийной механики молча меняла бы байты слепка; *компонент на класс* —
пять имён под ручки калибровки, которые крутятся разом.
**Два подпотока дня.** Заказная сторона — судьба заказа: исход, моменты, дельта,
опоздание. Событийная сторона — порча событийного потока: потеря и дубль. Довод
за разделение — различимость по паспорту: правка заказной механики не двигает
хеши событий, правка событийной не двигает байты слепка, и по покрасневшим хешам
видно, какую сторону трогали. Прежние имена `DISCREPANCIES` и `LATECOMERS`
решения не переживают — они названы по классам витрины, а компонент называет
часть мира; новые стороны занимают те же позиции. Заказная сторона названа при
реализации — подпоток `ORDERS` на позиции 2; событийная — `BEACONS` на позиции
3: маячок счетчика либо не долетает, либо отправляется повторно. Отклонено:
*один компонент на всю судьбу* — правка событийной механики молча меняла бы
байты слепка; *компонент на класс* — пять имён под ручки калибровки, которые
крутятся разом.
**Правило формы, без которого разделение не работает: броски заказной стороны
делаются на полную длину дня, а не на отобранных заказах.** Иначе длина броска
@@ -62,15 +62,14 @@
процентов» не заводим.
**Что из двух дорог видно.** В `dds.order` дороги неразличимы — там последняя
версия; различает их история версий: сырьё STG и физические версии
`ods.order` до фоновых слияний, а в витринах — выручка дня, которая
сначала выросла, потом убыла. Полное различение не обещано: слепок — состояние
на границе суток, и оплата с отменой в один день в сырье неразличимы; то же у
сильно опоздавших, приехавших уже терминальными. Точную форму этого урока
решает этап 4. Отклонено: *отмена только после оплаты* — неоплаченному некуда
деться, кроме как остаться брошенным; *мгновенная отмена при рождении* —
«дыхание» окна на отменах исчезает; *отмен нет вовсе* — страховочный срез 1,
он в резерве.
версия; различает их история версий: строки STG и физические версии `ods.order`
до фоновых слияний, а в витринах — выручка дня, которая сначала выросла, потом
убыла. Полное различение не обещано: слепок — состояние на границе суток, и
оплата с отменой в один день в сырых данных неразличимы; то же у сильно
опоздавших, приехавших уже терминальными. Точную форму этого урока решает этап
4. Отклонено: *отмена только после оплаты* — неоплаченному некуда деться, кроме
как остаться брошенным; *мгновенная отмена при рождении* — «дыхание» окна на
отменах исчезает; *отмен нет вовсе* — страховочный срез 1, он в резерве.
## Классы расхождений и опоздание
+4 -4
View File
@@ -24,10 +24,10 @@
Наблюдаемое обещание — четыре свойства: назначенные заказы пары с разных
`ClientID` несут один `user_id`; событие Метрики не раскрывает `user_id`;
отдельные прогоны одного мира дают то же соответствие; принятый мир
воспроизводит эффект склейки без случайных ложных объединений — конкретные
числа пар контрактом описи не являются. Межкогортные столкновения принимаются
по той же дисциплине, что у случайных `ClientID`: принимается конкретный
канонический мир по внешнему результату.
воспроизводит эффект склейки без случайных ложных объединений. Паспорт не
закрепляет конкретное число пар. Межкогортные столкновения принимаются по той же
дисциплине, что у случайных `ClientID`: принимается конкретный канонический мир
по внешнему результату.
Отклонено: *заказная сторона сама назначает личность* — родство кук всё равно
пришлось бы спрашивать у плана; *материализованный реестр кука↔пользователь* —
+12 -11
View File
@@ -35,10 +35,11 @@ PARTITION` могла бы заменить партицию дня неполн
После завершения генератора Airflow один раз читает байтовый Kafka-чтец и
записывает полученную порцию в `stg.orders_raw`. Даг зовётся `orders_ingest`, а
дёргает его тот, кто положил слепок в топик, — работник пульта мира, — и ждёт
конца прогона. Все строки получают `_load_id`, равный `run_id` Airflow.
запускает его шаговый даг модельного времени, который положил слепок в топик и
ждёт конца прогона. Все строки получают `_load_id`, равный `run_id` Airflow.
`_load_ts` вычисляется при этой записи и дальше переносится без пересчёта.
Запрос забора лежит в [`sql/stg/orders_raw_load.sql`](../../../sql/stg/orders_raw_load.sql):
Запрос забора лежит в
[`sql/stg/orders_raw_load.sql`](../../../sql/stg/orders_raw_load.sql):
`SQLExecuteQueryOperator` задаёт подключение и передаёт `run_id` как параметр
ClickHouse `load_id`, а преобразование остаётся в SQL своего слоя.
@@ -157,7 +158,7 @@ dbt snapshots — стратегия `check` вместо `timestamp`.
Отказ — случай другой, и «хвост дождётся» на него не распространяется. Офсеты
порции коммитятся в момент чтения, поэтому упавшая вставка уносит прочитанное с
собой: повторное чтение вернёт ноль, а часть строк может уже лежать на шарде.
Позиция мира при этом не двигается, и тот же день уедет заново — в сырье он
Позиция мира при этом не двигается, и тот же день уедет заново — в STG он
окажется частичным дублем, а старый хвост, ушедший той же порцией, не вернётся
([ADR 0008](../../adr/0008-order-ingestion.md), «Следствия»).
@@ -191,10 +192,10 @@ dbt snapshots — стратегия `check` вместо `timestamp`.
## Что проверено
Переход STG → ODS снят на живом стенде 18 августа 2026 года при исполнении #94.
Опыты этого раздела прогнаны и подтвердили обещанное: разбиение сырья на годные
строки и брак полное и непересекающееся; две версии одного заказа легли в одну
партицию и на один шард, а `ods.order_v` вернуло позднюю независимо от фонового
слияния; повтор задачи с тем же `_load_id` строку в `ods.order_v` и её
Опыты этого раздела прогнаны и подтвердили обещанное: разбиение строк STG на
годные строки и брак полное и непересекающееся; две версии одного заказа легли в
одну партицию и на один шард, а `ods.order_v` вернуло позднюю независимо от
фонового слияния; повтор задачи с тем же `_load_id` строку в `ods.order_v` и её
`_load_ts` не изменил, а таблица ошибок записала тот же брак второй раз; строки
опытов убраны. Числа, механика опытов и поведение ClickHouse, на которое всё это
опирается, — [документ хранилища](../storage.md), «Что проверено».
@@ -217,9 +218,9 @@ dbt snapshots — стратегия `check` вместо `timestamp`.
Текущее состояние проверено на пересобранном мире 26 августа 2026 года при
исполнении #165. После двух слепков физическая таблица содержала 3356 версий
1917 заказов. У всех строк `ods.order_v` дата слепка совпала с последним
слепком заказа; деловые поля совпали с эталоном `argMax` по `updated_at` из
сырья. В обеих сверках расхождений нет.
1917 заказов. У всех строк `ods.order_v` дата слепка совпала с последним слепком
заказа; деловые поля совпали с эталоном `argMax` по `updated_at` из сырых
данных. В обеих сверках расхождений нет.
Забор из Kafka в STG снят на живом стенде 18 августа 2026 года при исполнении
#93: одно прямое чтение приносит весь слепок дня, метаданные доставки доступны,
+12 -12
View File
@@ -1,20 +1,20 @@
# Что хранит опись
# Что хранит паспорт мира
Резолюции развилок [«Расхождения A–D и опоздания: механика, доли и что
обещано»](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/72)
и [«Места заказов в стартовом
мире»](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/74).
Словарь описи — растяжка-хеш против опоры-счётчика — задан «Чем меряется
генератор» в [спеке генератора](../../specs/2026-08-01-generator.md) и
термином «Опись мира» в [CONTEXT.md](../../../CONTEXT.md).
Термины паспорта — «растяжка-хеш» и «опора-счётчик» — заданы разделом «Чем
меряется генератор» в [спеке генератора](../../specs/2026-08-01-generator.md) и
статьёй «Паспорт мира» в [CONTEXT.md](../../../CONTEXT.md).
> Опись хранит только то, чего движение мира не меняет.
> Хеш кладём всегда, счётчик — только когда назван его читатель.
> Паспорт хранит только то, чего движение мира не меняет. Хеш кладём всегда,
> счётчик — только когда назван его читатель.
- **У каждого отправленного слепка — своя строка с хешем байтов.** Байты
слепка не покрыты хешами дней ни при каком раскладе подпотоков — это второй
артефакт мира. Побайтовое обещание («слепок переснимается и даёт те же
байты») опись начинает сторожить.
артефакт мира. Побайтовое обещание («слепок переснимается и даёт те же байты»)
паспорт начинает сторожить.
- **Счётчики классов расхождений — наблюдаемых, после приоритета**, по
итоговой судьбе заказов дня. В строке закрытого дня поле `orders` хранит
число заказов каждого класса; пока окно открыто, поля нет. При N сыгранных
@@ -24,7 +24,7 @@
- **Контрольные числа идентичности не заводятся вовсе**: uniq известных
пользователей и число двухкуковых пар растут, пока мир едет, — опоры из них
не выходит; генератор сторожит хеш, транспорт — счёт событий.
- **Опись описывает мир, а не доставку.** Работа генератора кончается на
Kafka: дошли ли байты до `ods.order` — вопрос стенда и его
проверок. Поэтому счёта строк у слепка в описи нет; понадобится проверка
приёма заказов — число заведётся вместе с ней.
- **Паспорт описывает мир, а не доставку.** Работа генератора кончается на
Kafka: дошли ли байты до `ods.order` — вопрос стенда и его проверок. Поэтому
счёта строк у слепка в паспорте нет; понадобится проверка приёма заказов —
число заведётся вместе с ней.
+2 -2
View File
@@ -112,5 +112,5 @@
такого значения означает ошибку арифметики источника.
Сверх контракта здесь живёт одно правило: **порядок строк внутри слепка —
порядок рождения заказов, он же возрастание `order_id`**. Детерминизм даёт
его даром, а хешу слепка в описи нужен именно названный порядок.
порядок рождения заказов, он же возрастание `order_id`**. Детерминизм даёт его
даром, а хешу слепка в паспорте нужен именно названный порядок.
+8 -8
View File
@@ -25,11 +25,11 @@
Цена принята с открытыми глазами: у части пар стартового мира поздний
назначенный заказ падает на день 7, и до первого хода мира этих пар в
`dds.identity_map` нет. Опись пар не считает
([что хранит опись](inventory.md)), поэтому красной проверки из этого не
выходит. Отклонено: *дослать восьмой слепок* — исчезает `awaiting_order` на
свежем стенде, в CLI заводится рычаг, стартовый мир становится особым случаем
ровно там, где #71 его убирал; *счётчик пар учится спрашивать про слепки* —
число верно ровно до первого хода мира; *отменить сдвиг отправки* —
`awaiting_order` пропал бы навсегда; *подогнать план под горизонт* — мир
перестал бы быть чистой функцией зерна.
`dds.identity_map` нет. Паспорт пар не считает ([что хранит
паспорт](inventory.md)), поэтому красной проверки из этого не выходит.
Отклонено: *дослать восьмой слепок* — исчезает `awaiting_order` на свежем
стенде, в CLI заводится рычаг, стартовый мир становится особым случаем ровно
там, где #71 его убирал; *счётчик пар учится спрашивать про слепки* — число
верно ровно до первого хода мира; *отменить сдвиг отправки* — `awaiting_order`
пропал бы навсегда; *подогнать план под горизонт* — мир перестал бы быть чистой
функцией зерна.