15 KiB
Автономное тройное ревью П38 · апрель 2021 · «Согласованность данных между сервисами»
Статус: авторское тройное ревью пройдено, затем пакет принят независимым редактором в выпусковой набор. Пакет содержит три revision для стабильных slug:
editorial-2021-04-practice-data-consistency;editorial-2021-04-mechanism-data-consistency;editorial-2021-04-field-data-consistency.
Созданы только пять разрешённых файлов:
web/scripts/upgrade-2021-04.mjs;editorial/reviews/2021-04-draft.md;web/public/assets/editorial/2021/data-consistency-state-machine-2021.svg;web/public/assets/editorial/2021/data-consistency-compensation-2021.svg;web/public/assets/editorial/2021/data-consistency-diagnosis-2021.svg.
Revision-модуль экспортирует только изменяемые редакционные поля. В нём нет
date, author или подключения registry.
articles.json, README, очередь, стандарты, package config и Git
не менялись. Команды --print-revisions и
--verify-fixture предназначены только для import-safe проверки
этого пакета.
Проход 1. Факты, историческая рамка и техника — пройдено
| Утверждение | Первичный или официальный источник | Проверенная граница |
|---|---|---|
Контекст события может включать id, source и type; version 1.0.1 CloudEvents уже существовала к апрелю 2021 года |
CloudEvents Specification v1.0.1: release record | Учебный конверт заимствует только понятные поля. Он не является полной реализацией CloudEvents, transport binding или broker API. |
| PostgreSQL 13 документирует локальную transaction isolation, serialization failure и необходимость retry в соответствующих случаях | PostgreSQL 13: Transaction Isolation | Это граница одной базы owner-а. Она не делает атомарными две базы, event delivery и внешний reserve API. |
INSERT ... ON CONFLICT задаёт альтернативу для unique/exclusion constraint в одном PostgreSQL-хранилище |
PostgreSQL 13: INSERT | compensation_key примера защищает повтор локального решения, а не доказывает cross-service consistency. |
| Kafka 2.7 отделяет producer idempotence и ограничивает её одной session, отдельно предупреждая о application-level resend | KafkaProducer 2.7.0 API | Set event id fixture подавляет один duplicate event только в памяти; статьи не обещают exactly-once business effect. |
Технический сценарий намеренно ограничен одним учебным object id
order-417. Owner сначала находится в paid v2.
Проверенный учебный reason training-reservation-rejected даёт
owner-у право создать cancelled v3 с единственным
compensationKey. Consumer получает v3 раньше v2, сохраняет
version gap, применяет v2 и затем replay-ит отложенную v3. Повтор v2/v3 не
создаёт новый state transition.
Инварианты fixture:
- owner не создаёт вторую компенсацию для того же
compensationKey; - consumer не меняет projection при gap и не двигает version назад;
- duplicate event id не создаёт второй state transition;
cancelled v3не разрешает следующий эффектreadyToShip.
Fixture использует только Array, Map и Set одного Node-процесса. Она не запускает database, broker, HTTP service, external reserve, real order, transaction manager или distributed delivery. Компенсирующее действие в статьях описано как паттерн решения owner-а, не как единый стандарт или готовая platform capability.
Вердикт прохода: пройден. Источники существовали к апрелю 2021 года, а проверенные факты не расширены до обещания общей транзакции, готового distributed workflow или exactly-once business effect.
Проход 2. Редактура, глубина и голос М4 — пройдено
Final draft audit подтвердил объём 5–15 тыс. знаков. Тексты держат короткую прагматичную речь «симптом → причина → проверка → действие» и М4 апреля 2021 года: ownership, инвариант, evidence и ограниченная компетентность вместо claims о распределённой платформе.
| Revision | Симптом и цена в первых двух абзацах | Главный вопрос | Итоговый объём |
|---|---|---|---|
| Практика | owner и fulfillment показывают разные versions; цена — совершить отгрузку или другой effect по отставшей проекции | Как назвать owner, инвариант следующего действия и границу eventual consistency | 10 294 знака body |
| Механизм | v3 приходит до v2 и duplicate повторяется; цена — перепрыгнуть переход, откатить projection назад или создать вторую компенсацию | Почему event id, version и compensation key нельзя заменить одним идентификатором | 10 790 знаков body |
| Полевой разбор | статусы расходятся, оператору хочется переписать их вручную; цена — потерять evidence и получить второй effect | Как собрать evidence packet и выбрать безопасное действие до replay | 11 728 знаков body |
Редакторский проход подтвердил:
- table с
caption/thead, figure с содержательнымalt/figcaption, не менее двух технических примеров и нумерованный маршрут в каждой revision; - явное различение owner state, consumer projection, version gap, duplicate event и compensation key;
- отсутствие claims о реальных заказах, замеренном lag, exactly-once, production delivery и зрелой distributed platform;
- отсутствие анахронизма: источники и версия Kafka/PostgreSQL/CloudEvents существовали к апрелю 2021 года, а паттерн не выдан за стандарт.
Вердикт прохода: пройден. Все три материала начинают с наблюдаемого расхождения и цены, затем дают конкретный owner/инвариант/evidence/route. Риторическая формулировка про «магический rollback» была заменена до финального audit на точное описание ложной границы компенсации.
Проход 3. Визуал, fixture и preflight — пройдено
Три SVG подготовлены как вертикальные схемы для 375 px:
- state machine отделяет owner v2/v3 от отложенной consumer projection;
- compensation показывает проверенный reason, локальный key и новое owner решение;
- diagnosis ведёт от блока рискованного effect к evidence packet, version branch и контролируемому действию.
Во всех SVG предусмотрены title, desc и
role="img"; отсутствуют JavaScript, foreignObject,
external URL и raster data URI. В первой статической проверке нижняя подпись
state machine оказалась слишком длинной для 375 px; она сокращена, SVG
отрендерен и просмотрен повторно.
cd web && node --check scripts/upgrade-2021-04.mjs
cd web && npm run audit:draft -- scripts/upgrade-2021-04.mjs
cd web && node scripts/upgrade-2021-04.mjs --verify-fixture
cd web && xmllint --noout \
public/assets/editorial/2021/data-consistency-state-machine-2021.svg \
public/assets/editorial/2021/data-consistency-compensation-2021.svg \
public/assets/editorial/2021/data-consistency-diagnosis-2021.svg
| Проверка | Реальный результат |
|---|---|
node --check |
PASS, code 0 |
| Import-safe export и draft gate | PASS: итоговые 10 294 / 10 790 / 11 728 знаков body; для всех трёх slug найдены sections, table, figure, code, route, sources и локальные SVG |
| In-memory fixture | PASS: итоговые десять assertions равны true; v3 сначала defer, затем v2 и replay v3; duplicate не меняет projection; другой event с занятой version отклоняется; компенсация записывается один раз; cancelled не разрешает effect |
xmllint --noout |
PASS, все три SVG — корректный XML |
| SVG safety scan | PASS: не найдены script, foreignObject, external URL или raster data URI |
| Sharp mobile preflight | PASS: финальные PNG 375×656, 375×667 и 375×719 просмотрены вручную; clipping, overlap и horizontal overflow внутри схем не обнаружены |
| Scope/self-review | PASS: созданы только пять разрешённых файлов; revision не меняют date/author; registry, archive, README, очередь, standard, package config, Git и чужие untracked files не редактировались |
npm run audit:draft завершилась с code 0. npm вывел старые
предупреждения о пользовательских store-dir, cache-dir
и public-hoist-pattern; они не относятся к П38 и не менялись
пакетом.
До независимой интеграции автономный автор не заявлял strict registry audit, production build, browser, screen reader, database/broker/API checks, deployment, commit или push.
Независимая интеграционная приёмка
Основной редактор 31 июля 2026 года подключил три revision к
web/data/editorial-revisions.mjs, сохранив базовый
articles.json, даты и автора архивных записей. В registry стало
109 revision, строгий аудит проходит 118 из 358 материалов.
В независимом техническом проходе найден один риск в учебном guard: новый
event с уже занятой orderVersion, но с другим id,
мог бы изменить projection. До выпуска guard был уточнён: сначала проверяется
subject, затем такой event возвращает
same-version-event-rejected; конфликт в отложенной версии также
не перезаписывает evidence. Fixture получила десятый assertion, а механизм и
полевой маршрут — явное правило не выбирать конфликт по времени получения.
Это изменение не выдаётся за transport guarantee.
CloudEvents release record подтверждает выпуск 1.0.1 в декабре 2020 года; версионная документация PostgreSQL 13 подтверждает границы локальной изоляции и retry при serialization failure; Kafka 2.7 отдельно ограничивает producer idempotence одной session и не дедуплицирует application-level re-send. Эти источники сверены независимо и использованы только в названных границах.
| Проверка после интеграции | Реальный результат |
|---|---|
| Import-safe export | PASS: три revision, без date/author |
| Строгий audit трёх slug | PASS: 10 294 / 10 790 / 11 728 знаков; у каждой статьи есть figure, table и code examples |
| Fixture после редакторского исправления | PASS: все 10 assertions истинны, включая rejection другого event с той же version |
| Независимый SVG review | PASS: XML и active/external asset scan прошли; три PNG 375 px просмотрены повторно, clipping, overlap и overflow не обнаружены |
| Production build | PASS: Next.js собрал 374 статические страницы |
Ни этот отчёт, ни интеграция не утверждают запуск broker, SDK, HTTP, базы, external API, browser или assistive technology.
Выпусковой вердикт: ACCEPT. Commit и push выполняются отдельной публикационной операцией; Git остаётся источником её фактической записи.