Files
progcode/editorial/reviews/2027-04-draft.md
T
huncode 21b249b6c6
Build and deploy / deploy (push) Successful in 16s
revise April 2027 build evolution plan articles
2026-07-31 20:28:42 +03:00

14 KiB
Raw Blame History

P110 — April 2027: «Эволюция frontend-сборки»

Статус, temporal boundary и write scope

Редакторская дата: 2026-07-31. Апрель 2027 ещё не наступил. Три статьи — явно помеченный план/сценарий на 2027-04 с source cutoff 2026-07-31. В них не существуют и не заявляются: реальный config, CI artifact, build timing, cache hit, bundle size, migration, tool release, build result, winner, rollout или production change.

Очередь P110 запрашивает исторические config/CI-артефакты и одинаковый build-замер. В этом наборе они смоделированы только как именованные поля synthetic shape со значением not-collected; это не данные, не фрагменты системы и не скрытая методика. Единственный разрешённый положительный output — synthetic-plan-hand-off, всегда с productionEffect: not-attempted.

Изменены только:

  • web/scripts/upgrade-2027-04.mjs
  • editorial/reviews/2027-04-draft.md
  • web/public/assets/editorial/2027/build-evolution-2027-configuration-timeline.svg
  • web/public/assets/editorial/2027/build-evolution-2027-comparable-conditions-matrix.svg
  • web/public/assets/editorial/2027/build-evolution-2027-evidence-handoff-loop.svg

Registry, README, articles.json, app, queue, P102–P109 и Git state не менялись.

Pinned official primary sources

  1. webpack — Caching guide, immutable source snapshot, official webpack documentation at immutable b7fa07c852d24449e9445717c41395bdd2ca4784, resolved on source cutoff 2026-07-31. Используется только для терминов output/content hash/cache как частей configuration; не доказывает local config, timing, artifact или размер.
  2. actions/cache v4.2.3 — immutable README, official GitHub Action at immutable 5a3ec84eff668545956fd18022155c47e93e2684, pinned before source cutoff 2026-07-31. Используется только для различения cache key, restore и save; не подтверждает workflow, runner, cache hit или запуск.
  3. SLSA v1.0 — Provenance, official SLSA specification v1.0, pinned before cutoff. Используется как vocabulary для provenance артефакта; не утверждает существование, создание или проверку attestation.

Все источники первичные, official, фиксированы не позднее cutoff. Никаких источников о будущих релизах инструментов, будущем CI или будущих build results не использовано.

Review pass 1 — редакционный фокус, голос и temporal honesty

  • Practice: сравнение configuration до названия инструмента. В первых двух абзацах названы цена ложного «новая лучше» и цена выдуманной CI-картины. Timeline ведёт к question hand-off, а не к migration result.
  • Mechanism: cache, CI, artifact и предел inference. В первых двух абзацах разделены разные слои evidence и цена сравнения разных условий. Matrix отделяет future provenance от недопустимых выводов о timing, hit и размере.
  • Field: передача synthetic evidence, а не build report. В первых двух абзацах названы цена ложной операционной памяти и подмена пустой карточки полевым отчётом. Loop заканчивается future owner, не approval или rollout.
  • Все тексты держат M10: прагматичный русский технический голос, без hype по инструментам и без retrospective tone. У каждого есть mechanism, доступная HTML table, meaningful русский alt/caption, runnable safe example, ordered actions, limitations и next step.

Review pass 2 — literal safety, отсутствие фактов и fail-closed

  • configuration-hand-off-v1 требует planDate: 2027-04, sourceCutoff: 2026-07-31, две named synthetic configurations, named comparableCondition со state not-collected, а также config, ci, buildTiming, cacheHit и bundleSize строго not-collected.
  • undated-future-scenario-v1 возвращает stop-undated-future-scenario-or-cutoff.
  • missing-comparable-condition-v1 возвращает stop-missing-comparable-condition.
  • hidden-configuration-or-cache-assumption-v1 возвращает stop-hidden-configuration-or-cache-assumption; скрытая configuration и assumed cache не получают default.
  • disallowed-positive-result-v1 возвращает stop-disallowed-positive-result; нельзя заявить build improvement, migration или иной future outcome.
  • Factory делает JSON clone fixed literal и recursive deep freeze, включая historicalArtifacts. Evaluator принимает только JSON-равный известный literal; unknown или mutation fail-closed. Модуль не читает файлы или конфигурацию, не запускает build/CI/cache и не обращается к environment, clock, network, secrets, telemetry или production.

Review pass 3 — accessibility, visual inspection и uniqueness

  • Все три SVG имеют русские title и desc, а статьи — осмысленные русские alt/caption. В SVG нет URL, измеренных значений или claims о build result.
  • XML/safety проверка исключает script, foreignObject, javascript:, data:image и inline handlers.
  • Sharp 375 px visual inspection проведена по PNG. Timeline: читаются четыре верхних шага, обе stop-ветви и подпись. Matrix: сохраняются пять строк, четыре колонки и нижний красный guard. Loop: различимы вход, дата, сравнимость, hand-off и центральный stop; текст не обрезан.
  • Strict pairwise uniqueness включает code и исключает section Проверяемые источники. Для каждой пары shared-12-word-fragments=0.

Actual checks and results

Выполнено из web/:

node --check scripts/upgrade-2027-04.mjs
node scripts/upgrade-2027-04.mjs --verify-fixture
npm run audit:draft -- scripts/upgrade-2027-04.mjs
node --input-type=module -e "import { createFixedBuildCase, assessFixedBuildPlan } from './scripts/upgrade-2027-04.mjs'; const ids=['configuration-hand-off-v1','undated-future-scenario-v1','missing-comparable-condition-v1','hidden-configuration-or-cache-assumption-v1','disallowed-positive-result-v1']; for (const id of ids) console.log(id, assessFixedBuildPlan(createFixedBuildCase(id)).status); const accepted=assessFixedBuildPlan(createFixedBuildCase()); console.log('exports-frozen', Object.isFrozen(createFixedBuildCase()), Object.isFrozen(createFixedBuildCase().historicalArtifacts), accepted.productionEffect);"
xmllint --noout public/assets/editorial/2027/build-evolution-2027-configuration-timeline.svg public/assets/editorial/2027/build-evolution-2027-comparable-conditions-matrix.svg public/assets/editorial/2027/build-evolution-2027-evidence-handoff-loop.svg
! rg -n -i '<(script|foreignObject)\\b|javascript:|data:image|(?:^|[[:space:]])on[a-z]+=' public/assets/editorial/2027/build-evolution-2027-configuration-timeline.svg public/assets/editorial/2027/build-evolution-2027-comparable-conditions-matrix.svg public/assets/editorial/2027/build-evolution-2027-evidence-handoff-loop.svg
node --input-type=module -e "import sharp from 'sharp'; for (const n of ['build-evolution-2027-configuration-timeline','build-evolution-2027-comparable-conditions-matrix','build-evolution-2027-evidence-handoff-loop']) await sharp('public/assets/editorial/2027/'+n+'.svg').resize({width:375}).png().toFile('/private/tmp/'+n+'-375.png');"
node --input-type=module -e "import { revisions } from './scripts/upgrade-2027-04.mjs'; const text=h=>h.replace(/<h2>Проверяемые источники<\\/h2>[\\s\\S]*/, '').replace(/<[^>]+>/g,' ').replace(/&(?:quot|amp|lt|gt|#039);/g,' ').toLowerCase().replace(/[^a-zа-яё0-9]+/giu,' ').trim().split(/\\s+/); const grams=a=>new Set(a.slice(0,-11).map((_,i)=>a.slice(i,i+12).join(' '))); let failed=false; for(let i=0;i<revisions.length;i++) for(let j=i+1;j<revisions.length;j++){const left=text(revisions[i].contentHtml), right=text(revisions[j].contentHtml), common=[...grams(left)].filter(x=>grams(right).has(x)); console.log(revisions[i].slug+' <> '+revisions[j].slug, 'shared-12-word-fragments='+common.length); if(common.length){failed=true;console.log(common.join('\\n'));}} if(failed) process.exitCode=1;"

Результаты фактического запуска:

  • Syntax: PASS, exit 0.
  • Fixture и article guards: PASS 8/8; fixture 5/5, все три article checks true.
  • Exact body chars, без section sources: editorial-2027-04-practice-build-evolution — 10846; editorial-2027-04-mechanism-build-evolution — 11098; editorial-2027-04-field-build-evolution — 9766. Каждый текст находится в общем диапазоне 5k–15k и целевом 9k–13k.
  • Draft audit: PASS для трёх exact slugs.
  • Literal public exports: PASS. Статусы cases: synthetic-plan-hand-off, stop-undated-future-scenario-or-cutoff, stop-missing-comparable-condition, stop-hidden-configuration-or-cache-assumption, stop-disallowed-positive-result; exports-frozen true true not-attempted.
  • xmllint: PASS без output. SVG safety scan: PASS, rg не нашёл запрещённый content.
  • Sharp rendering и 375 px manual inspection: PASS для всех трёх SVG.
  • Strict pairwise duplicate scan (code included, sources excluded): PASS. practice <> mechanism = 0, practice <> field = 0, mechanism <> field = 0 shared 12-word fragments.

Единственный не-failing output — существующие npm warnings о неизвестных user config store-dir, cache-dir, public-hoist-pattern; audit прошёл, warnings не относятся к P110.

Независимая приёмка — 2026-07-31

Проход 1 — источники, постановка и голос

  • Mutable guide links заменены на проверяемые immutable snapshots: webpack.js.org commit b7fa07c852d24449e9445717c41395bdd2ca4784 и actions/cache v4.2.3 commit 5a3ec84eff668545956fd18022155c47e93e2684. Оба первичных источника доступны по закреплённым путям; SLSA остаётся версионной спецификацией v1.0.
  • Проверена фактическая граница claim: источники задают терминологию content hash, cache key/restore/save и provenance, но ни один не превращён в доказательство local config, CI run, cache hit, bundle size или migration.
  • У всех трёх статей собственная цена ошибки и самостоятельный вопрос: сравнимость config, уровни evidence и честная передача будущему владельцу. Автор говорит о стоимости решения и воспроизводимом методе, не рекламируя bundler.

Проход 2 — исполнимый контракт и автоматический аудит

  • node --check, fixture 8/8, literal export/deep-freeze check и npm run audit:draft -- scripts/upgrade-2027-04.mjs завершились успешно. Длины body: 10 890, 11 098 и 9 766 знаков.
  • Пять fixed cases дают ровно один synthetic-plan-hand-off и четыре fail-closed stop-ветви; positive result и скрытая config/cache assumption не проходят. Accepted branch сохраняет productionEffect: not-attempted.
  • xmllint прошёл без output; SVG safety scan не нашёл executable или external active content.

Проход 3 — визуал, повторяемость и выпуск

  • Три SVG отрендерены и просмотрены в ширине 375 px: timeline, матрица и loop сохраняют заголовки, ячейки, стрелки и stop-блоки без обрезки.
  • Cross-package scan P102–P110 включает код и исключает источники. Первый запуск выявил шесть общих 12-словных фрагментов у practice runnable example с P108/P109; example переписан как отдельная boolean-проверка question contract. Повторный запуск по 27 статьям: collisions: [].
  • В реестр добавлены только три апрельские revisions; пользовательские app/data files не включены.