12 KiB
Ноябрь 2019 — тройное ревью автономного пакета P21 «Воспроизводимые сборки»
Статус: принят в publication registry 31 июля 2026 года. Три revision накладываются только по stable slug и сохраняют даты и авторов базового архива:
editorial-2019-11-practice-reproducible-builds;editorial-2019-11-mechanism-reproducible-builds;editorial-2019-11-field-reproducible-builds.
Модуль экспортирует ровно три revision. В объектах нет date и
author: эти поля принадлежат исходным записям архива. При прямом
запуске с --print-revisions stdout содержит только JSON; отдельный
--run-fixture печатает JSON учебной hash-проверки.
Проход 1. Факты и техника — пройдено
| Утверждение или решение | Первичный источник | Проверенная граница |
|---|---|---|
| Lockfile фиксирует конкретное дерево, включая транзитивные зависимости | npm 6: package-locks и package-lock.json | Текст не утверждает, что lockfile фиксирует OS, время, webpack config или внешний генератор. Он фиксирует разрешение пакетов, когда используется в контролируемом install. |
npm ci — чистая установка с отказом при рассинхронизации lockfile и package.json |
npm 6: npm ci | Статьи не подменяют им рабочий npm install и не обещают, что npm ci устраняет drift плагина или даты в asset. |
| npm config может прийти из CLI, окружения, npmrc и package.json | npm 6: npm config | В журнал предлагается whitelist безопасных значений, а не полный env, токены или auth headers. |
[contenthash] связан с содержимым asset, но runtime и module IDs способны расширить diff chunks |
webpack: Caching | Имя одного файла названо сигналом, а не доказательством равенства всего dist. Проверяется manifest всех deployable files. |
| SHA-256 нужен для сравнения выбранных bytes | Node.js: Crypto | Hash не объявлен подписью релиза, доказательством работы приложения или результатом production-сборки. |
Автономная fixture не скачивает зависимости и не запускает webpack. Она проверяет только алгоритм сравнения: перестановка одинаковых entries даёт тот же hash manifest, изменение одного bytes даёт другой. Фактический вывод:
{
"fixtureOnly": true,
"lockfileSha256": "d2976c1b0ca05326497d2b8157ee39b3ffc6f5ad6481c119e2fd769d3e6c8204",
"firstManifestSha256": "adc6fefae98f7874289579da4efcf252217989cbc9caf32fc8bb830f6eeac75e",
"secondManifestSha256": "adc6fefae98f7874289579da4efcf252217989cbc9caf32fc8bb830f6eeac75e",
"changedManifestSha256": "a521a4c7df02a402a2ab7e71ff690554cdf686faf831aaefe7d171079d15e8fe",
"checks": {
"sameEntriesDifferentOrder": true,
"changedFileChangesManifest": true
}
}
Следовательно, fixture подтверждает только канонизацию sample manifest. В пакете нет заявления о CI, registry install, браузерном релизе или production output. Для настоящего проекта статьи требуют записать собственные commit, lockfile digest, Node/npm, команду, журнал и manifest после реального запуска.
Проход 2. Редактура и голос М2 / 2019 — пройдено
| Ревизия | Симптом и стоимость в начале | Главный технический вопрос | Проверяемый результат и ограничение |
|---|---|---|---|
| Практика | Один commit создаёт два dist; review и rollback не знают, какой набор assets был проверен | Как получить два чистых прогона, не смешав установку зависимостей и проверку output | Lockfile/log/manifest route, Node hash script и список входов; нет заявления о запуске этого проекта |
| Механизм | Одинаковый Git hash скрывает разные runtime, config или generated data | Где проходит граница функции build и что доказывает manifest SHA-256 | Карта входов, таблица владельцев, контрпримеры contenthash; hash не выдан за подпись или тест приложения |
| Полевой разбор | Коллеги получили разные release-файлы и хотят начать с очистки cache | Как по первому differing file отличить dependency, config и generated output | Карточка двух прогонов, дерево диагностики и обратимый путь исправления; CI и production не заявлены |
- Тон соответствует уровню М2 / 2019: npm 6, webpack 4, Node, проектный npmrc, чистая установка, manifest и diff. В текст не добавлены поздние практики вроде supply-chain attestations, SLO, распределённой трассировки или риторика платформенного техлида.
- Во всех трёх текстах держится маршрут «симптом → причина → проверка →
действие → ожидаемый результат → ограничение». Конкретные объекты названы:
package-lock.json,npm ci,dist,first.manifest,NODE_ENV, runtime chunk и generated banner. - Нет шаблонных призывов «очистить кэш», «закрепить всё» или «сделать CI» без диагностического условия. Каждый такой шаг имеет место в маршруте, владельца и границу вывода.
- Draft gate подтвердил основной текст в диапазоне 5 000–15 000 символов: 10 061 для практики, 9 115 для механизма и 8 650 для полевого разбора. В значение не включены title, meta и раздел источников.
- В каждой статье есть не менее пяти
h2, доступная таблица сcaption,theadиscope, оригинальная схема с содержательнымиalt/figcaption, код, упорядоченный маршрут и не менее двух официальных источников.
Проход 3. Визуал и выпуск автономного пакета — пройдено
reproducible-build-input-contract-2019.svgведёт от исходников, зависимостей и среды/команды к чистой установке, build и manifest. Диаграмма подчёркивает, что hash приходит после явного контракта, а не заменяет его.reproducible-build-hash-boundary-2019.svgотделяет зафиксированные commit/lockfile от runtime, config и generated data. Нижняя развилка не называет расхождение ошибкой сборщика: она ведёт к первому отличающемуся файлу.reproducible-build-diagnosis-2019.svgпоказывает две чистые сборки, сравнение входов и явное условие: при расхождении входов маршрут останавливается, при совпадении сравнивается output manifest. Это визуальный маршрут, а не скриншот несуществующего прогона.- В каждом SVG есть
title,desc,role="img", вертикальныйviewBox, контрастные карточки и подписи внутри заданной ширины. Нет JavaScript, внешних URL, растровых вложений или анимации. XML-валидатор принял все три файла. - Независимый mobile preflight отрисовал каждый SVG через Sharp в PNG шириной 375 px. Первый raster показал мелкие подписи в горизонтальных панелях и обрезание диагностической схемы. Все три визуала пересобраны вертикально; повторный рендер не показал обрезания, наложения или горизонтального выхода. Это проверка статичных изображений, а не browser screenshot или Accessibility tree.
- После подключения registry strict audit и production build пройдены. Ручной browser-review поведения страницы остаётся отдельной выпускной проверкой и не заявлен как выполненный.
Выполненные команды
cd web
node --check scripts/upgrade-2019-11.mjs
npm run audit:draft -- scripts/upgrade-2019-11.mjs
node scripts/upgrade-2019-11.mjs --run-fixture
xmllint --noout \
public/assets/editorial/2019/reproducible-build-input-contract-2019.svg \
public/assets/editorial/2019/reproducible-build-hash-boundary-2019.svg \
public/assets/editorial/2019/reproducible-build-diagnosis-2019.svg
Все четыре команды завершились с кодом 0. Draft gate вывел:
PASS editorial-2019-11-practice-reproducible-builds: 10061 body chars
PASS editorial-2019-11-mechanism-reproducible-builds: 9115 body chars
PASS editorial-2019-11-field-reproducible-builds: 8650 body chars
После интеграции strict audit подтвердил: 10 061 / 9 115 / 8 650 знаков,
по одному figure и table, 3 / 1 / 1 code example. npm run build
завершился с кодом 0 и сгенерировал 374 статические страницы.
Выпусковой вердикт: тройное ревью пройдено, пакет принят к публикации.
articles.json не менялся; registry заменяет только редакционные
поля по stable slug. Production build и raster preflight не подменяют ручную
проверку поведения в браузере.