rewrite 2026-09 and 2027 articles for reader-facing quality
Build and deploy / deploy (push) Successful in 18s

This commit is contained in:
2026-07-31 22:26:56 +03:00
parent 3bfc3f21c4
commit 440c8721dc
69 changed files with 4424 additions and 3533 deletions
+38 -68
View File
@@ -1,87 +1,57 @@
# P107 — January 2027: «Десять лет web-диагностики»
# Январь 2027 — редакторское ревью после переписывания
## Статус, граница времени и scope
## Объём партии
Редакторская дата: **31 июля 2026**. Январь 2027 ещё не наступил. Все три текста прямо обозначены как **план/сценарий на 2027-01** с source cutoff **2026-07-31**. Это не ретроспектива о завершённых десяти годах, не historical report и не описание реального incident.
Переписаны три самостоятельные технические статьи с сохранением stable slug:
Для P107 нет bug reports, logs, traces, repro, tool output, production incidents, customer data или historical artifacts. Очередь ожидает такие артефакты, но этот пакет их не создаёт и не имитирует. Термины из официальных источников отделены от synthetic модели: source говорит о формате или словаре, но не подтверждает конкретную web-систему, carrier, запись, причинность либо результат расследования.
- `editorial-2027-01-practice-debugging-decade` — 5 825 знаков основного текста;
- `editorial-2027-01-mechanism-debugging-decade` — 5 706 знаков;
- `editorial-2027-01-field-debugging-decade` — 5 640 знаков.
Исполняемый пример принимает только named fixed in-memory literals. Factory выполняет JSON clone, затем deep freeze; evaluator принимает только JSON-равный известный literal и fail-closed закрывает всё остальное. Он не читает и не меняет сеть, browser, файлы, environment, clock, secrets, telemetry backend, external tools или production. Единственный допустимый положительный output — `synthetic-plan-hand-off` с `productionEffect: not-attempted`; root cause, fix, rollout, report, incident и любой положительный production conclusion запрещены.
Внутри body нет планов выпуска, временных границ редакции, synthetic hand-off, статусов отсутствующих данных, отчёта о создании текста или сюжета о развитии автора. Траектория проявлена только в спокойной речи техлида: симптом, граница, проверка, действие, ограничение.
Изменены только следующие файлы:
## Проход 1 — факты, техника, пример и источники
- `web/scripts/upgrade-2027-01.mjs`
- `editorial/reviews/2027-01-draft.md`
- `web/public/assets/editorial/2027/debugging-decade-2027-evolution-timeline.svg`
- `web/public/assets/editorial/2027/debugging-decade-2027-signal-tool-limit-table.svg`
- `web/public/assets/editorial/2027/debugging-decade-2027-hypothesis-evidence-loop.svg`
Проверялись смысл HTTP/trace/log, соответствие примеров заявленному предмету, версии и границы официальных источников.
Registry, README, `articles.json`, app, очередь, P102–P106 и Git-state не менялись.
- **Practice.** До: статья вела от абстрактной карты диагностики к передаче вопроса. После: первый кодовый пример классифицирует `502/504`, `401/403` и пустой `200` через `classifyWebSymptom`. Причина: читатель получает предметный следующий сигнал, а не описание редакционной модели.
- **Mechanism.** До: связь trace и log описывалась как фиксированный набор полей. После: `linkTraceRecords()` строит parent-граф и явно показывает `missing parent`. Причина: проверяется реальный разрыв контекста, а не только терминология trace.
- **Field.** До: полевой текст заканчивался передачей неполной карточки. После: `buildRequestTimeline()` соединяет access и application events по точному `requestId` и различает `gateway-failed-before-app` и `app-error-reached-client`. Причина: пример отвечает на вопрос разбора 502.
## Pinned primary sources и границы
Источники сверены точечными запросами и применены с границами:
1. [W3C Trace Context](https://www.w3.org/TR/2021/REC-trace-context-1-20211123/), W3C Recommendation, 23 November 2021. Использован только для терминологической границы стандартизированного propagation trace context. Не подтверждает trace, carrier, связь или причинность в P107.
2. [RFC 5424: The Syslog Protocol](https://www.rfc-editor.org/rfc/rfc5424), March 2009, DOI `10.17487/RFC5424`. Использован только для различения формата protocol message и фактической записи. Не создаёт log record, report или history.
3. [NIST SP 800-92: Guide to Computer Security Log Management](https://doi.org/10.6028/NIST.SP.800-92), September 2006, DOI `10.6028/NIST.SP.800-92`. Использован как общий контекст дисциплины provenance и log management. Не подтверждает сбор, retention, incident или расследование.
- [W3C Trace Context](https://www.w3.org/TR/trace-context/) — Recommendation, 23 November 2021; формат `traceparent` и передача контекста; не доказывает полноту цепочки или причинность.
- [RFC 5424](https://www.rfc-editor.org/rfc/rfc5424.html) — Standards Track, March 2009; structured data и границы syslog-сообщения; не гарантирует доставку журнала приложения.
- [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html) — Internet Standard, June 2022; семантика HTTP 502/504/401/403; не описывает конкретную топологию сервиса.
- [NIST SP 800-92](https://csrc.nist.gov/pubs/sp/800/92/final) — September 2006; управление источником, временем и содержимым журналов; не является evidence конкретной системы.
Все три источника первичные, pinned и не позднее cutoff. Имена fixed cases, статусы, правило «evidence не сильнее input», диаграммы, таблицы и safe hand-off — собственная synthetic модель P107, не вывод этих источников.
## Проход 2 — структура, голос, плотность и мета-лексика
## Review pass 1 — три разных редакционных фокуса
- **Practice.** До: вступление начиналось с общего разговора о диагностике. После: первые два абзаца называют 502/пустой ответ, цену случайного фикса и минимальный конверт симптома. Причина: читатель сразу понимает, что именно проверять.
- **Mechanism.** До: лог, span и metric смешивались в одном объяснении. После: отдельные разделы и таблица разводят сильный вопрос каждого инструмента и запрещённый вывод. Причина: короткая техническая речь не скрывает границу ответственности.
- **Field.** До: один общий совет «посмотреть логи» повторялся в нескольких местах. После: текст разделён на edge, application, время/retry и последовательность пяти действий. Причина: каждый абзац добавляет наблюдение или решение.
- **Practice**: аккуратная карта от synthetic симптома к именованной гипотезе и planned signals. В первых двух абзацах названы ранний прыжок к причине и ретроспективный вымысел; цена — обратные изменения, шум и ложная память. Статья не предлагает универсальный метод и не приписывает историю конкретной команде.
- **Mechanism**: что не меняется между log, trace, metric и новым UI: named input, правило связи, альтернативное объяснение и предел силы вывода. В начале названа ложная причинность по id и цена — исключение не исключённых альтернатив. Отдельно разведены schema, поле, collector, время и evidence.
- **Field**: synthetic debugging hand-off без field artifact. В начале названа передача «причина подтверждена» без материала и цена — ложная операционная память. Таблица и схема описывают лишь форму будущей передачи; они не называют project, tool, person, incident, время или production effect.
- Голос M10: короткая прагматичная русская техническая речь наставника, с прямыми ограничениями и без обещания одного метода для всех систем.
Проверка body по запрещённым шаблонам (`synthetic-plan-hand-off`, `productionEffect`, `future-only`, `source cutoff`, `not-collected`, `not-attempted`, `future owner`, «развитие автора») дала `0` совпадений во всех трёх статьях. Внутри январской тройки и в общей партии января–апреля общих 12-словных фрагментов нет.
## Review pass 2 — literal safety и temporal integrity
## Проход 3 — визуал, мобильная читаемость, доступность и повторы
- Положительный `planned-handoff-v1` требует `planDate: 2027-01`, `sourceCutoff: 2026-07-31`, named symptom/hypothesis/signals и `evidence: synthetic-contract/input/not-collected`.
- `undated-scenario-v1` → `stop-undated-scenario-or-cutoff`.
- `unnamed-signal-v1` → `stop-unnamed-signal`; `unnamed-hypothesis-v1` → `stop-unnamed-symptom-or-hypothesis`.
- `evidence-stronger-than-input-v1` → `stop-evidence-stronger-than-input`: synthetic plan не может заявить `observed` или `claimed-collected` evidence.
- `positive-conclusion-v1` → `stop-disallowed-positive-conclusion`: `root-cause-confirmed` запрещён.
- Factory использует JSON clone и deep freeze, включая nested `signals`. Произвольный или изменённый input → `stop-unknown-fixed-input`. Допустимая ветка возвращает только `synthetic-plan-hand-off`, `productionEffect: not-attempted` и future evidence owner action.
- **Practice.** До: временная шкала содержала редакционные статусы. После: SVG показывает четыре русских шага «симптом → конверт → сигнал → действие» и красную ветку отсутствующего ключа. Причина: рисунок объясняет маршрут диагностики.
- **Mechanism.** До: схема показывала hand-off. После: диаграмма показывает симптом, две гипотезы, distinguishing signal и возврат к collector при разрыве. Причина: visual соответствует коду parent/request-id.
- **Field.** До: таблица и рисунок утверждали передачу несуществующего отчёта. После: рисунок показывает access → application → read-back и отдельную ветку разрыва; alt и caption называют поля. Причина: убрана мета-сюжетность и сохранена доступность.
## Review pass 3 — visuals, доступность, неповторяемость
Все три SVG имеют русские `<title>`/`<desc>`, содержательный `alt`, подпись, только локальные формы и проходят XML/safety scan. Каждая статья содержит доступную HTML-таблицу с `<caption>`, `<thead>` и `scope="col"`; узкие таблицы обёрнуты в `table-scroll`.
- У каждого SVG есть русские `title` и `desc`, а у соответствующей статьи — русские meaningful alt и caption. Изображения содержат механизм: timeline с двумя stop, сравнительную таблицу пределов inference и loop hand-off.
- XML validation прошла для всех трёх SVG. Safety scan не нашёл `script`, `foreignObject`, `javascript:`, `data:image` или inline event handlers; внешних ссылок в SVG нет.
- Sharp создал три PNG шириной 375 px. Ручной visual inspection подтвердил: заголовки и подписи не обрезаны; practice сохраняет все четыре узла и два stop; mechanism читает все четыре строки таблицы и красные запреты; field сохраняет направления синей и красных стрелок и читаемые stop-блоки.
- Строгий pairwise scan исключал section sources, но включал code. Общих точных фрагментов по 12 слов: practice/mechanism `0`, practice/field `0`, mechanism/field `0`.
## Проверки
## Actual verification commands and results
Запущено из `web/`:
```sh
node --check scripts/upgrade-2027-01.mjs
node scripts/upgrade-2027-01.mjs --verify-fixture
npm run audit:draft -- scripts/upgrade-2027-01.mjs
node --input-type=module -e "import { createFixedDiagnosticCase, assessFixedDiagnosticPlan } from './scripts/upgrade-2027-01.mjs'; const ids=['planned-handoff-v1','undated-scenario-v1','unnamed-signal-v1','unnamed-hypothesis-v1','evidence-stronger-than-input-v1','positive-conclusion-v1']; for (const id of ids) console.log(id, assessFixedDiagnosticPlan(createFixedDiagnosticCase(id)).status); const accepted=assessFixedDiagnosticPlan(createFixedDiagnosticCase()); console.log('exports-frozen', Object.isFrozen(createFixedDiagnosticCase()), Object.isFrozen(createFixedDiagnosticCase().signals), accepted.productionEffect);"
xmllint --noout public/assets/editorial/2027/debugging-decade-2027-evolution-timeline.svg public/assets/editorial/2027/debugging-decade-2027-signal-tool-limit-table.svg public/assets/editorial/2027/debugging-decade-2027-hypothesis-evidence-loop.svg
! rg -n -i "<(script|foreignObject)\\b|javascript:|data:image|(?:^|[[:space:]])on[a-z]+=" public/assets/editorial/2027/debugging-decade-2027-evolution-timeline.svg public/assets/editorial/2027/debugging-decade-2027-signal-tool-limit-table.svg public/assets/editorial/2027/debugging-decade-2027-hypothesis-evidence-loop.svg
node --input-type=module -e "import sharp from 'sharp'; for (const n of ['debugging-decade-2027-evolution-timeline','debugging-decade-2027-signal-tool-limit-table','debugging-decade-2027-hypothesis-evidence-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-01.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(' '))); 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) console.log(common.join('\\n'));}"
```text
node --check scripts/upgrade-2027-01.mjs — PASS
node scripts/upgrade-2027-01.mjs --verify-fixture — PASS, 4/4
npm run audit:draft -- scripts/upgrade-2027-01.mjs — PASS, 3/3
локальные примеры module exports — PASS, 12/12 для всей партии
xmllint --noout для 3 SVG — PASS
SVG safety scan (script, foreignObject, javascript, data:image, event handlers) — PASS
Sharp resize width=375 для 3 SVG — PASS; визуально проверены заголовки, стрелки, таблица и красные ветки
strict cross-article scan января–апреля: 12 статей, 66 сравнений, sources excluded, code included — collisions: []
```
Results:
- Syntax: PASS (`node --check` exit 0).
- Fixture and article guard: PASS `9/9`; fixture `6/6`; all three article checks `true`.
- Article volumes: practice `9,066`, mechanism `9,041`, field `9,238` body characters; all are within the required 5,000–15,000 range and the 9–13k target.
- `npm run audit:draft`: three PASS lines, one per exact required slug.
- Public literal exports: PASS. Six status results exactly matched their expected branches; `exports-frozen true true not-attempted`.
- `xmllint`: PASS with no output. SVG safety: PASS, `rg` found no forbidden content. Sharp render: PASS for all three outputs; all three 375 px PNG files were visually inspected.
- Pairwise duplicate scan: PASS, `shared-12-word-fragments=0` for all three pairs, with code included and sources excluded.
The only non-failing command output was the existing npm warning about unknown user config (`store-dir`, `cache-dir`, `public-hoist-pattern`); it did not affect the audit result.
## Независимая приёмка основного редактора — 31.07.2026
Принято только как **плановый выпуск на январь 2027**. Названы `2027-01` и cutoff `2026-07-31`; нет вымышленной декады, incident, log, trace, repro или production-вывода. Positive output не сильнее `synthetic-plan-hand-off` c `productionEffect: not-attempted`.
W3C Trace Context заменён на датированную Recommendation 23.11.2021, чтобы ссылка не указывала на изменяемую current-страницу. RFC 5424 и NIST SP 800-92 остаются первичными источниками формата и log-management vocabulary; все три источника используются только для терминов, не для доказательства route, carrier, записи или причинности P107.
Повторные проверки: syntax; fixture/guard `9/9` (fixture `6/6`); draft audit с объёмами 9 266 / 9 041 / 9 238; XML и SVG safety-scan. Literal exports подтвердили все six expected branches, включая `stop-unnamed-signal`, `stop-unnamed-symptom-or-hypothesis`, `stop-evidence-stronger-than-input` и `stop-disallowed-positive-conclusion`. Sharp PNG трёх SVG осмотрены на 375 px: подписи, строки таблицы, arrows и stop labels читаемы. После замены формата practice snippet строгий cross-package scan 18 статей августа 2026 — января 2027 дал `collisions: []`.
В registry добавлены только три январские ревизии. Пользовательские application-файлы, `articles.json`, production queue и прочая незакоммиченная работа не входят в приёмку.
Git, registry, README, `articles.json`, приложение и файлы других месяцев не изменялись.