function escapeHtml(value) { return String(value).replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", '''); } const p = (text) => '
' + text + '
'; const h2 = (text) => '' + escapeHtml(text) + '';
const ol = (items) => '| ' + cell + ' | ').join('') + '
|---|
| ' + cell + ' | ').join('') + '
named-fixed-synthetic-portfolio-case. Он существует только как literal в памяти модуля. Имена narrow-evidence-note и expanded-evidence-note не обозначают репозитории, команды, сервисы или реальные документы. Они нужны, чтобы у структуры были различимые варианты. Такая бедная модель полезнее правдоподобной декорации: она не позволяет читателю достроить отсутствующую производственную историю.'),
p('Структура case narrative не обязана вести к успеху. Контекст отвечает, какая именно проблема рассматривается и какую цену ошибки надо удержать. Варианты показывают пространство до сужения. Решение в будущем плане — лишь правило, по которому кто-то позже сможет выбрать форму работы; это не принятое решение. Evidence описывает силу входа и допустимую силу утверждения. Residual risk фиксирует остаток, который нельзя стереть хорошим изложением. Если один слой пропущен, текст не становится короче и яснее: он начинает притворяться тем, чего в нём нет.'),
figure('/assets/editorial/2026/portfolio-case-2026-causal-timeline.svg', 'Причинная временная линия synthetic сценария на декабрь 2026: проблема и варианты ведут к плановой структуре, затем к границе evidence и residual risk; красные точки останавливают недатированный сценарий, пропущенный отклонённый вариант и слишком сильное доказательство.', 'Оригинальная схема структуры будущего сценария. Это порядок проверки narrative, а не временная линия уже произошедшего проекта или rollout.'),
table('Пять полей планового case narrative', ['Поле', 'Что допустимо в сценарии', 'Что запрещено заявлять', 'Проверка границы'], [
['Контекст', 'одна редакторская проблема и цена её ошибки', 'существование конкретного проекта или инцидента', 'пометка synthetic и будущая дата'],
['Варианты', 'два named literals и один явно rejected option', 'что варианты реально оценивали', 'rejected option должен быть назван'],
['Решение', 'planned-structure-only', 'утверждённый ADR или выбор', 'результат не шире hand-off'],
['Evidence', 'scenario-only, fixed-plan-brief, not-collected', 'benchmark, metric, test или наблюдение', 'claimStrength равен inputStrength'],
['Residual risk', 'следующий открытый риск и будущий владелец evidence', 'что риск снят или rollout разрешён', 'productionEffect остаётся not-attempted'],
]),
h2('Контекст начинается с цены, но не с легенды'),
p('Контекст должен быть узким. В synthetic модели проблема не «команда плохо документирует решения», а «будущий читатель может принять плановую форму narrative за доказательство уже состоявшегося результата». Цена — ложная память: позднее появляется ссылка на якобы выполненный тест или на якобы принятую архитектурную запись, а её нельзя предъявить. Такая формулировка не требует придумать пользователей, сроки, бюджет и технику. Она даёт проверяемую границу именно для текста.'),
p('Полезно отделять цену ошибки от размера выгоды. Цена отвечает, что будет испорчено, если утверждение окажется лишним: доверие к источнику, возможность пересмотреть решение, время следующего владельца. Она не сообщает, что будущая работа окупится, ускорится или снизит число ошибок. Пока нет реальных входов, такие обещания сильнее модели. Поэтому в первом абзаце этой статьи названа цена ложного основания, а не прогноз эффекта.'),
h2('Варианты нужны, чтобы решение было обратимым'),
p('В сценарии имеются два варианта формы: narrow-evidence-note и expanded-evidence-note. Первый оставляет только границу входов и следующий вопрос. Второй добавил бы правдоподобные детали, которые нечем проверить. Literal заранее помечает второй как rejectedOption, но не потому, что он хуже в реальной редакции. Это учебное правило модели: если rejected option не назван, evaluator возвращает stop-missing-rejected-option. Он не подставляет вариант по умолчанию.'),
p('Отклонённый вариант важен не для драматургии. Он показывает, какой соблазн сознательно не был превращён в факт. В реальном будущем кейсе варианты могут быть другими, их число может вырасти, а основания потребуют отдельных источников. Этого сейчас нет. Нельзя написать, что expanded note отвергли на review, потому что review не происходил. Корректнее сказать: фиксированный literal задаёт такую ветку, чтобы проверить, что структура не потеряет альтернативу при передаче.'),
h2('Решение в плане — это только форма будущего вопроса'),
p('Слово «решение» особенно опасно: оно легко звучит как готовый ADR. Здесь decision: planned-structure-only означает ровно обратное. Модель предлагает порядок полей, который можно передать будущему владельцу evidence. Она не выбирает технологию, не меняет код, не назначает автора и не подтверждает приоритет. При желании назвать это decision нужно одновременно назвать отсутствие полномочий и отсутствующие inputs; без этих слов читатель увидит утверждение, которого literal не содержит.'),
p('Такое ограничение не обесценивает narrative. Напротив, оно даёт будущему обсуждению место для изменения. Если появится другой вариант, его можно добавить до отдельного разрешённого evidence contract. Если риск окажется важнее, его можно вынести в критерий. Если источник не относится к вопросу, его можно убрать без переписывания легенды о результате. Обратимость исчезает, когда рассказ уже пообещал, что «мы решили и доказали».'),
h2('Evidence должен быть слабым ровно настолько, насколько слаб вход'),
p('У synthetic case вход имеет силу scenario-only. Единственная запись — fixed-plan-brief, состояние — not-collected. Поэтому claimStrength обязан быть тем же scenario-only. Это не шкала качества и не оценка вероятности. Это предохранитель от ретроспективной подмены: текст, основанный на плановом literal, не может вдруг получить статус «benchmark confirmed» только потому, что такой вывод выглядит убедительнее.'),
p('Evaluator сравнивает эти поля до разрешения положительной ветки. При несоответствии он возвращает stop-evidence-stronger-than-input. Stop не сообщает, что будущий benchmark невозможен; он сообщает, что его нельзя утверждать на основании этого входа. Иными словами, это проверка происхождения claim, а не измерение самой системы. В коде нет сборщика метрик, клиента тестов, доступа к папке, сети или календарю. Есть только фиксированная схема, которую можно прочитать целиком.'),
h2('Runnable literal показывает форму, не исполняет проект'),
code("import { createFixedPortfolioCase as makePlan, assessFixedPortfolioCase as assessPlan } from './upgrade-2026-12.mjs';\n\nconst decemberPlan = makePlan('portfolio-case-plan-v1');\nconst handoff = assessPlan(decemberPlan);\nconsole.log({ state: handoff.status, effect: handoff.productionEffect, next: handoff.nextAction });\n// { state: 'synthetic-plan-hand-off', effect: 'not-attempted', next: 'hand-the-synthetic-boundary-to-a-future-evidence-owner' }"),
p('Пример запускается локально как импорт этого модуля и работает лишь с named fixed in-memory literal. Factory делает JSON clone, затем deep freeze рекурсивно замораживает объект; это предотвращает незаметную замену вложенного evidence после получения экземпляра. Freeze не является защитой production-системы и не доказывает истинность текста. Он нужен для узкого свойства примера: одни и те же literals дают один и тот же ограниченный status.'),
p('Ни положительная, ни stop-ветка не имеют побочного эффекта. Они не открывают browser, не читают файл, не используют environment, часы, секреты, telemetry или внешние инструменты. В частности, нет вызова, который создаёт ADR, запускает benchmark, собирает метрику, исполняет тест или меняет rollout. У единственной разрешённой положительной ветки status: synthetic-plan-hand-off и productionEffect: not-attempted. Это safe hand-off будущего вопроса, не результат.'),
h2('Residual risk нельзя прятать в финальном абзаце'),
p('В fixed case residual risk назван явно: будущему владельцу может понадобиться отдельный evidence contract. Это не риск конкретной инфраструктуры и не прогноз инцидента. Он указывает на незакрытую логическую работу: определить допустимые реальные inputs, метод получения и правило интерпретации. Пока такого контракта нет, никакая аккуратная проза не превращает scenario-only в observed proof. Поэтому residual risk расположен в данных, а не оставлен как настроение автора.'),
p('Не следует компенсировать этот пробел очередью вымышленных артефактов. Нельзя приписать плану будущий ADR, обещанный benchmark, тестовый протокол, метрику или incident review. Даже фраза «после rollout проверим» делает rollout частью истории, хотя он не начинался. Допустимый следующий шаг скромнее: передать boundary владельцу, который в будущем и при отдельном разрешении сможет решить, нужен ли evidence contract. Сам владелец здесь не назначается.'),
h2('Нумерованный маршрут для будущего сценария'),
ol(['В первой строке пометить материал как план/сценарий на 2026-12 и указать source cutoff 2026-07-31.', 'Сформулировать один synthetic контекст и цену неверного утверждения без названий реальных систем.', 'Назвать как минимум два fixed варианта и явно отметить вариант, который не переносится дальше.', 'Записать planned structure вместо решения, ADR или рекомендации.', 'Сопоставить силу каждого claim с силой входа; при усилении вернуть stop, а не красивый вывод.', 'Оставить residual risk и передать только safe hand-off с productionEffect: not-attempted.']),
h2('Ограничения и следующий шаг'),
p('Эта статья не даёт шаблон для публикации реального postmortem и не заменяет архитектурное, правовое, security или эксплуатационное рассмотрение. NIST и RFC ниже используются лишь как pinned первичные источники терминологии риска и силы нормативных слов. Они не подтверждают существование этого synthetic case, не задают его варианты и не разрешают считать plan фактом. Все поля модели — редакционные literals, действующие только в границе P106.'),
p('Следующий шаг возможен только в будущем: получатель safe hand-off может сформулировать отдельный evidence contract и получить необходимые полномочия. До этого корректный результат не расширяется. Нельзя переименовать hand-off в completed case задним числом, потому что это уничтожит provenance. Для декабря 2026 честная точка остановки уже полезна: она оставляет карту вопроса, но не изображает путь, который ещё не пройден.'),
], [
{ key: 'nistRisk', use: 'Первичный источник использован только для терминов риска и неопределённости.', boundary: 'Не подтверждает synthetic case, результат, ADR, benchmark или rollout.' },
{ key: 'rfc2119', use: 'Первичный RFC использован для различения силы требований в формулировках.', boundary: 'Не создаёт решение и не делает сценарий проектным фактом.' },
{ key: 'rfc8174', use: 'Первичный RFC уточняет контекст BCP 14.', boundary: 'Не доказывает evidence и не разрешает положительный production outcome.' },
]);
const mechanism = revision({
slug: 'editorial-2026-12-mechanism-portfolio-case', title: 'Инженерный кейс без ретроспективного proof: причинность и контрфакты', categories: ['Инженерные практики', 'Качество'], cover: '/assets/editorial/2026/portfolio-case-2026-tradeoff-ledger.svg', excerpt: 'План на декабрь 2026: как не усилить proof задним числом и проверять причинную цепочку через контрфакты.', readingMinutes: 20,
}, [
p('Плановый инженерный кейс ломается, когда итог пишут раньше механизма: рядом оказываются изменение и хороший исход, а связь между ними объявляют доказанной. Цена ошибки — причинность становится декорацией. Следующий читатель не видит альтернативное объяснение, не может воспроизвести входы и получает готовый вывод, который выглядит сильнее любых данных, реально доступных в материале.'),
p('Есть и более тихий сбой: к декабрю 2026 ещё нет будущего evidence, но текст использует лексику завершённого benchmark, метрики, теста или rollout. Цена — задним числом созданный proof: план начинают цитировать как отчёт, а вымышленная уверенность проходит дальше, чем исходный сценарий. Эта статья прямо является планом/сценарием на 2026-12 с source cutoff 2026-07-31. В ней не произошли проектный кейс, ADR, benchmark, метрика, тест, инцидент, change, rollout или результат.'),
h2('Механизм начинается с различия события, наблюдения и claim'),
p('Причинность не равна соседству слов. Для утверждения «изменение вызвало эффект» нужны как минимум названные входы, правило наблюдения, сравнение и граница интерпретации. В нашем fixed scenario ничего этого не собрано: evidence.state равно not-collected. Поэтому он не моделирует реальное событие и даже не моделирует измерение. Он моделирует только дисциплину: из планового входа нельзя вывести сильнее, чем «есть плановый literal».'),
p('Это различие удобно держать в трёх строках. Событие — то, что могло произойти в мире; здесь нет названного события. Наблюдение — запись, полученная разрешённым способом; здесь нет наблюдения. Claim — фраза, которую допускает материал; здесь разрешён только scenario-only. Если смешать строки, получится типичная ретроспектива: «мы сделали X, поэтому Y улучшилось», хотя X не подтверждён, Y не измерен, а «поэтому» лишь связывает два желаемых предложения.'),
figure('/assets/editorial/2026/portfolio-case-2026-tradeoff-ledger.svg', 'Ledger причинных утверждений для synthetic сценария на декабрь 2026: вход scenario-only допускает только claim scenario-only; контрфакты и отсутствующие наблюдения удерживают красный stop для benchmark-claim и completed result.', 'Оригинальная схема баланса claim и входа. Она не содержит фактов о системе и не показывает реально достигнутый trade-off.'),
table('Ledger силы утверждения', ['Слой', 'Fixed literal', 'Допустимый вывод', 'Контрфактический вопрос'], [
['Вход', 'scenario-only, fixed-plan-brief', 'есть только плановая модель', 'что изменится, если literal вообще не использовать?'],
['Наблюдение', 'not-collected', 'наблюдения нет', 'какая запись отличила бы эффект от шума?'],
['Claim', 'scenario-only', 'safe hand-off вопроса', 'можно ли получить тот же claim без события?'],
['Результат', 'synthetic-plan-hand-off', 'передача границы будущему владельцу', 'не назван ли здесь completed case?'],
]),
h2('Контрфакт нужен не для гадания, а для запрета лишнего вывода'),
p('Контрфакт в этом материале не предсказывает параллельную реальность. Это контрольный вопрос к языку. Если без реального input можно написать тот же «успешный результат», значит claim не зависит от evidence и слишком силён. Например, benchmark-confirmed в literal выглядел бы как факт, хотя единственная запись всё ещё fixed-plan-brief. Убрать такой literal из воображаемого мира ничего не меняет в тексте, потому что benchmark никогда не был входом. Следовательно, утверждение нельзя пропустить.'),
p('Второй контрфакт касается вариантов. Если удалить expanded-evidence-note, история всё ещё может звучать гладко, но больше нельзя проверить, от чего именно отказалась структура. Так выявляется причина, не связанная с эффектом: автор мог просто спрятать неудобный путь. Поэтому evaluator требует named rejected option. Это не доказательство качества narrow note; это условие, что narrative остаётся сравнимым с вариантом, который не переносится дальше.'),
h2('Причинная цепочка должна иметь видимые разрывы'),
p('У причинной цепочки в будущем кейсе должны быть отдельные звенья: вопрос, допустимый input, способ наблюдения, правило сравнения, claim, residual risk. Наш сценарий намеренно останавливается после первого звена. Это важно проговаривать, а не обозначать многоточием. Неопределённость не исчезает от того, что автор аккуратно описал потенциальный метод. План протокола не является протоколом; поле not-collected не является плохим замером; отсутствие change не является нулевым эффектом.'),
p('Отсюда следует практическое правило для редактора: не писать глаголы прошлого времени там, где literal хранит будущую дату и не собранные inputs. Нельзя сказать «проверили», «зафиксировали», «измерили», «выкатили» или «устранили». Даже нейтральное «результат показал» превращает форму отчёта в claim. Для этого P106 использует декабрь как явную temporal boundary и cutoff как границу доступной терминологии. Они не позволяют приписать будущему сценарию историю из головы.'),
h2('Fail-closed сравнивает силу, а не правдоподобие текста'),
p('В validator нет эвристики, которая угадывает честность автора. Он сравнивает буквальные поля. Если inputStrength не scenario-only, если claimStrength отличается от него или state перестаёт быть not-collected, возвращается stop-evidence-stronger-than-input. Так deliberately неверный literal evidence-stronger-than-input-v1 не получает оценку «сомнительно»: его нельзя передать как allowed output.'),
p('Важно, что stop не становится обратным доказательством. Он не говорит, будто выбранный вариант опасен, будто будущий benchmark даст отрицательный результат или будто реальное изменение невозможно. Он фиксирует только несоответствие claim и входа. Такой узкий смысл делает статус пригодным для hand-off: следующий владелец понимает, что надо снизить claim либо создать отдельный разрешённый источник, но не получает ложного диагноза системы.'),
h2('Runnable example проверяет контрфактную границу'),
code("import { createFixedPortfolioCase as loadCase, assessFixedPortfolioCase as checkClaim } from './upgrade-2026-12.mjs';\n\nconst overclaim = loadCase('evidence-stronger-than-input-v1');\nconst verdict = checkClaim(overclaim);\nconsole.log({ blocked: verdict.status, repair: verdict.nextAction, effect: verdict.productionEffect });\n// { blocked: 'stop-evidence-stronger-than-input', repair: 'reduce-the-claim-to-the-fixed-input', effect: 'not-attempted' }"),
p('Этот runnable fragment не создаёт искусственный benchmark и не читает результат из внешнего мира. Он берёт заранее описанный отрицательный literal, клонирует его JSON clone и получает deep-frozen экземпляр. Затем evaluator замечает, что claim benchmark-confirmed сильнее scenario-only input. Результат — stop с указанием ремонта. Никакой метрики, теста, trace, файла, сети, browser, environment, clock, secret или telemetry здесь нет.'),
p('Контрфактическая польза примера в другом: если заменить literal разрешённым планом, «доказанный benchmark» не возникнет сам. Значит успешный текст не зависит от скрытого вычисления или случайного состояния среды. Это свойство тестового примера, а не доказательство для будущего проекта. JSON clone устраняет shared reference, deep freeze удерживает вложенные значения, а fixed named cases не дают передать произвольный объект под видом source. Внешняя валидность по-прежнему отсутствует.'),
h2('Не путайте proof, provenance и аккуратную ссылку'),
p('Pinned первичный источник может сообщать, что документ NIST описывает риск или что RFC определяет силу нормативных слов. Это provenance внешнего термина. Он не делает причинную связь конкретного будущего кейса доказанной. Proof в реальном смысле потребовал бы собственных разрешённых входов и метода; у нас их нет. Ссылка не должна закрывать эту дыру авторитетом: её boundary в конце статьи прямо отделяет терминологию от synthetic model.'),
p('Provenance literals проще: caseName, planDate, cutoff, имя rejected option, состояние evidence и status. Это след происхождения модели, а не журнал проекта. Его ценность в том, что читатель может увидеть предел claim без чтения подтекста. Поэтому model не хранит правдоподобные идентификаторы задач, имена команд, timestamps или показатели. Такие подробности создали бы видимость доказательства, но не добавили бы входов.'),
h2('Разделяйте конкурирующие объяснения до языка результата'),
p('Даже в будущем разрешённом исследовании один приятный сигнал не отвечает на вопрос о причине. Эффект мог бы совпасть с изменением времени, выбором иной группы входов, другой конфигурацией или способом отбора наблюдений. P106 не заполняет эти альтернативы выдуманными значениями. Он использует их как запрет на удобную сокращённую фразу: пока не названо, с чем сравнивали и что могло объяснить разницу без действия, нельзя писать причинный итог.'),
p('Для plan narrative это означает полезную симметрию. Нужно записать не только предполагаемое действие, но и условие, при котором его влияние будет неразличимо. Не «новая структура даст понятный hand-off», а «без отдельного evidence contract невозможно узнать, дала ли структура что-либо за пределами понятного hand-off». Такая запись сохраняет вопрос открытым и не требует изображать контроль, период или величину эффекта. Она также помогает будущему владельцу не принять отсутствие наблюдений за отрицательный результат.'),
p('Контрфакт не нужно прятать в примечании. Его можно положить рядом с claim как проверяемое ограничение: какой минимум input делает эту фразу недопустимой? В synthetic literal ответ прост: любой claim сильнее scenario-only должен быть остановлен. В будущем реальном contract ответ наверняка станет сложнее, но тогда он будет принадлежать тому contract, а не этому декабрьскому тексту. Смешивать уровни означало бы выдать учебное правило за метод исследования.'),
h2('Последовательность анти-ретроспективной проверки'),
ol(['Сначала выписать claim, который хочется поставить в заголовок, и проверить, существует ли для него вход.', 'Разделить событие, наблюдение и вывод; не склеивать их союзом «поэтому».', 'Задать контрфакт: остался бы тот же вывод, если убрать claimed input?', 'Назвать минимум один rejected option, чтобы история не выглядела единственно возможной.', 'Сравнить inputStrength и claimStrength literal-to-literal; при расхождении вернуть stop.', 'Передать только ограниченный status будущему владельцу evidence без слов о completed case.']),
h2('Ограничения и следующий шаг'),
p('Эта схема не является методом каузального анализа, статистическим тестом или шаблоном оценки эффекта. Она не устанавливает контрольную группу, период наблюдения, конфаундеры или порог решения. У неё нет данных, и именно поэтому она не симулирует числа. NIST SP 800-30, RFC 2119 и RFC 8174 ниже pinned до cutoff и помогают дисциплинировать термины; они не подтверждают проектную причинность и не создают будущие артефакты.'),
p('Следующий шаг возможен только после отдельного разрешения на evidence contract: будущий владелец должен назвать input, метод, границу сравнения и допустимый claim. До тех пор ответ P106 — либо конкретный stop, либо synthetic-plan-hand-off с productionEffect: not-attempted. Это не скромность ради стиля, а единственный результат, который не превосходит фиксированный synthetic input.'),
], [
{ key: 'nistRisk', use: 'Первичный источник использован для аккуратной терминологии риска и ограничений.', boundary: 'Не доказывает причинность, benchmark, метрику или результат будущего кейса.' },
{ key: 'rfc2119', use: 'Первичный RFC задаёт контекст силы нормативных формулировок.', boundary: 'Не превращает claim сценария в evidence.' },
{ key: 'rfc8174', use: 'Первичный RFC уточняет, когда применимы слова BCP 14.', boundary: 'Не заменяет контрфакт, наблюдение или review.' },
]);
const field = revision({
slug: 'editorial-2026-12-field-portfolio-case', title: 'Инженерный кейс как synthetic evidence hand-off', categories: ['Инженерные практики', 'Процессы'], cover: '/assets/editorial/2026/portfolio-case-2026-evidence-boundary-loop.svg', excerpt: 'План на декабрь 2026: безопасно передать synthetic evidence boundary, не придумав ADR, метрики, теста, инцидента или rollout.', readingMinutes: 20,
}, [
p('Будущая передача инженерного кейса часто терпит сбой ещё до работы: получателю отдают фразу «доказательства собраны», хотя существует только план обсудить evidence. Цена — потеря времени на поиск несуществующих ADR, метрик, тестов, инцидентов и rollout-записей. Затем команда спорит не о следующем вопросе, а о том, кто должен подтвердить красивый итог, который никогда не был разрешённым входом.'),
p('Вторая проблема — назвать такую передачу field report и тем самым добавить ей вес реального наблюдения. Цена — ложная операционная память: future reader может считать, что change уже произошёл и residual risk закрыт. Ничего подобного не заявляется. Это план/сценарий на 2026-12 с source cutoff 2026-07-31; декабрь ещё не наступил. Ни проектный кейс, ни ADR, ни benchmark, ни метрика, ни тест, ни инцидент, ни change, ни rollout, ни результат не произошли в этом материале.'),
h2('Field здесь означает адресата hand-off, а не полевое наблюдение'),
p('Слово field в названии удобно прочитать как «практический опыт». Здесь оно обозначает только форму передачи между будущими ролями. У отправителя есть fixed synthetic literal, у получателя — граница того, чего ещё нет. Между ними нет реальной системы, задачи в трекере, человека с назначенным дедлайном или production доступа. Это намеренная конструкция: если бы hand-off выглядел как рабочее поручение, он сам стал бы недоказанным событием.'),
p('Безопасная карточка передаёт не ответ, а структуру отсутствия. В ней есть дата плана, source cutoff, контекст, два варианта, rejected option, сила входа, состояние not-collected, residual risk, status и nextAction. В ней нет ссылки на dashboard, номера ADR, результата теста, графика метрики, текста incident review или обещания rollout. Получатель не обязан верить автору на слово: он может открыть literal и увидеть, что положительная ветка не шире safe synthetic hand-off.'),
figure('/assets/editorial/2026/portfolio-case-2026-evidence-boundary-loop.svg', 'Петля передачи границы evidence для synthetic сценария на декабрь 2026: карточка с date, cutoff, options и scenario-only передаётся будущему владельцу; красные возвраты блокируют недатированный сценарий, отсутствующий rejected option, усиленный claim и positive result.', 'Оригинальная схема safe synthetic evidence hand-off. Она показывает маршрутизацию статусов, а не фактический workflow, запуск или результат.'),
table('Карточка безопасной передачи', ['Поле', 'Значение fixed scenario', 'Чего получатель не должен выводить', 'Следующее допустимое действие'], [
['Время', 'planDate 2026-12; cutoff 2026-07-31', 'что работа уже шла в декабре', 'сохранить future boundary'],
['Варианты', 'narrow и expanded note; один rejected', 'что был реальный дизайн-review', 'уточнить только структуру question'],
['Evidence', 'scenario-only; not-collected', 'что есть benchmark, test или metric', 'при необходимости предложить отдельный contract'],
['Output', 'handoff либо stop; not-attempted', 'что rollout, change или результат разрешён', 'передать boundary без исполнения'],
]),
h2('Передача начинается с того, что явно отсутствует'),
p('Обычная карточка статуса часто перечисляет сделанное. Для будущего synthetic case полезнее начать с отсутствующего: нет production inputs, нет наблюдения, нет решения, нет owner с полномочием на изменение. Это не пустота в документе, а его главный сигнал. Читатель должен увидеть отсутствие раньше, чем увидит красивую схему. Иначе даже аккуратные слова «план» и «сценарий» потеряются рядом с убедительными деталями, которые похожи на реальный кейс.'),
p('В fixed literal boundary перечисляет запрещённые поверхности: network, browser, file, environment, clock, secret, telemetry, external tool, customer и production system. Это не обещание изоляции всей редакционной среды. Это контракт конкретного runnable example: функция не обращается к этим поверхностям. По той же причине модель не создаёт ручку очереди и не отправляет уведомление. Safe hand-off — возвращаемый объект в памяти, а не операция над чужим процессом.'),
h2('Provenance позволяет не путать модель с доказательством'),
p('Provenance этой карточки короткий: named fixed case, JSON clone, deep freeze, planDate, cutoff и state evidence. Каждый элемент отвечает на свой вопрос. Имя говорит, что объект можно соотнести с ограниченным набором literals. Clone отделяет выданный экземпляр от константы. Freeze удерживает вложенные поля в текущем запуске. Дата и cutoff держат временную границу. State сообщает, что наблюдение не собрано. Вместе они не доказывают мир; они делают модель честно читаемой.'),
p('Не стоит превращать provenance в искусственный audit trail. Не нужны даты, похожие на время инцидента, не нужен ID change, не нужен автор с реальным именем и не нужен снимок якобы существующей панели. Такие детали не дают воспроизводимости, если не было источника. Они дают только поверхность для ложной ссылки. Здесь источники ограничены официальными pinned документами до cutoff и отделены от собственных literals в разделе внизу. Они объясняют слова, но не подтверждают карточку.'),
h2('Stop должен быть удобнее, чем скрытая эскалация'),
p('У сценария четыре опасные границы. stop-undated-scenario-or-cutoff возникает, когда дата плана или cutoff не совпадают с P106. stop-missing-rejected-option не позволяет сделать narrative одновариантным после факта. stop-evidence-stronger-than-input блокирует benchmark claim поверх scenario-only. stop-disallowed-positive-result не пропускает completed case, ADR, metric, test, incident, change или rollout под видом результата. Каждый status содержит nextAction и всегда productionEffect: not-attempted.'),
p('Это fail-closed поведение важно для hand-off. Если поле отсутствует, функция не заполняет его удобным дефолтом; если evidence выглядит правдоподобно, функция не присваивает ему доверие; если requested result звучит позитивно, функция не интерпретирует его как план. Статус не эскалирует вопрос во внешний мир. Он возвращает текстовую причину и следующий безопасный шаг. Получатель может исправить literal или оставить работу до появления отдельной власти и источников.'),
h2('Runnable example передаёт stop, а не притворный результат'),
code("import { createFixedPortfolioCase as prepareHandoff, assessFixedPortfolioCase as gateHandoff } from './upgrade-2026-12.mjs';\n\nconst incompleteStory = prepareHandoff('missing-rejected-option-v1');\nconst reply = gateHandoff(incompleteStory);\nconsole.log({ status: reply.status, action: reply.nextAction, production: reply.productionEffect });\n// { status: 'stop-missing-rejected-option', action: 'name-the-option-not-carried-forward', production: 'not-attempted' }"),
p('Этот пример выбирает опасный fixed literal, а не изменяет разрешённый объект на лету. JSON clone создаётся в памяти, после чего deep freeze защищает форму вложенных полей от mutation в процессе. Evaluator не читает реальные варианты и не пытается узнать, почему что-то отвергли. Он проверяет более скромное свойство: у передаваемого narrative должен быть явно назван rejected option. При его отсутствии он возвращает stop, а не домысливает историю.'),
p('Вызов не создаёт ADR, не собирает metric, не запускает test, не расследует incident, не вносит change и не инициирует rollout. Он не подключается к network, browser, file system, environment, clock, secrets, telemetry или внешнему инструменту. Это literal runnable example, а не эмулятор production. Его результат можно использовать как проверяемую демонстрацию boundary, но нельзя ссылаться на него как на evidence будущего кейса.'),
h2('Как передавать synthetic evidence boundary'),
p('Получателю полезно получить одну короткую фразу: «Вот fixed scenario на 2026-12; у него source cutoff 2026-07-31; evidence только scenario-only и not-collected; любое усиление claim вернёт stop; положительный исход не шире synthetic-plan-hand-off». Затем нужно приложить concrete nextAction, а не пожелание «провести исследование». В P106 nextAction адресует будущего evidence owner, но не назначает его и не создаёт ему задачу. Разница защищает boundary от скрытого внешнего действия.'),
p('Отправитель также должен оставить residual risk рядом с hand-off. Здесь он говорит, что будущему владельцу может понадобиться отдельный evidence contract. Нельзя писать, что контракт уже согласован, что данные будут доступны или что change безопасен. Эти предположения особенно быстро становятся «известным фактом» после нескольких пересказов. Полезнее сохранить риск как открытое условие и дать следующему читателю возможность не продолжать историю, пока он не может легально и технически уточнить входы.'),
h2('Граница hand-off не является очередью работ'),
p('Есть соблазн сделать карточку полезнее, сразу добавив исполнителя, срок и ожидаемый артефакт. Для P106 это был бы незаметный переход от модели к внешней координации. Фраза «владелец подготовит ADR» уже предполагает владельца, будущий ADR и запущенную работу; фраза «проверим метрику после change» предполагает change и набор метрик. Ни одно из этих предположений не находится в fixed input. Поэтому nextAction здесь описывает только класс будущего вопроса, а не чей-то назначенный action.'),
p('Такая граница защищает и получателя. Он может увидеть hand-off, не принимая на себя молчаливую обязанность. Он вправе остановиться, запросить полномочия или решить, что отдельный evidence contract не нужен. Документ не считает любой stop задержкой и не измеряет скорость закрытия. Его задача — не продавить продолжение правдоподобием narrative, а оставить выбор будущего пути открытым. Для безопасного planning hand-off это часто более полезно, чем список работ с фиктивной уверенностью.'),
p('Нужно различать также техническую возможность и разрешение. Модуль мог бы быть расширен файловым reader или API client, но наличие такой возможности не даёт права читать production данные. Аналогично, будущая команда могла бы создать тест, но это не означает, что тест уже запланирован, согласован или нужен. Текущий literal не хранит этих прав и не делает внешних вызовов. Ровно поэтому его положительный status остаётся передачей boundary, а не переходом к исполнению.'),
h2('Нумерованные действия перед передачей'),
ol(['Проверить, что заголовок и первая часть карточки называют план/сценарий на 2026-12 и source cutoff 2026-07-31.', 'Сверить caseName с named fixed synthetic literal; не подставлять произвольный объект.', 'Убедиться, что options содержат два имени и rejected option записан явно.', 'Оставить evidence как scenario-only и not-collected; не добавлять похожие на реальные records.', 'Отклонить любой requested positive result, кроме synthetic-plan-hand-off с productionEffect: not-attempted.', 'Передать status, reason, boundary, residual risk и nextAction без создания задачи, change или rollout.']),
h2('Ограничения и следующий шаг'),
p('Карточка не заменяет реальный evidence hand-off, потому что в ней нет реального evidence. Она не подтверждает качество будущего решения, безопасность изменения, совместимость вариантов или итог для пользователя. Нельзя использовать её как аргумент в security review, архитектурном совете или release decision. Первичные NIST и RFC в ссылках ниже ограничены терминологией: они опубликованы до cutoff, но не имеют отношения к данному fictional case и не снимают его residual risk.'),
p('Следующий шаг — не «довести кейс до результата», а в будущем отдельно решить, нужен ли и возможен ли evidence contract. До этого hand-off безопасно заканчивается в памяти функции. Положительная ветка не меняет мир и прямо несёт productionEffect: not-attempted. Это важнее привлекательного поля «результат»: документ остаётся usable для подготовки, но не производит фиктивную историю о том, что уже было сделано.'),
], [
{ key: 'nistRisk', use: 'Первичный источник использован только для словаря риска и ограничения утверждений.', boundary: 'Не является evidence для карточки и не подтверждает реальный hand-off.' },
{ key: 'rfc2119', use: 'Первичный RFC использован для аккуратной модальности требований.', boundary: 'Не назначает владельца, action или production change.' },
{ key: 'rfc8174', use: 'Первичный RFC уточняет применение BCP 14.', boundary: 'Не разрешает называть synthetic status фактом эксплуатации.' },
]);
export const revisions = deepFreeze([practice, mechanism, field]);
export function verifyRevisionsAgainstFixture() {
const fixture = runFixedPortfolioCaseFixture();
const articleChecks = revisions.map((revisionItem) => { const text = bodyText(revisionItem.contentHtml); return text.length >= 10000 && text.length <= 13000 && /(цен[аы]|стоимост|издержк)/i.test(text.slice(0, 1000)) && /