Files
progcode/editorial/agent-rewrites/037.json
T
huncode 2d914b543f
Build and deploy / deploy (push) Failing after 15s
Publish rewritten technical article archive
2026-08-02 22:19:34 +03:00

8 lines
21 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"index": 37,
"slug": "editorial-2026-12-field-portfolio-case",
"title": "Как передать инженерный кейс, не превратив сценарий в доказательство",
"excerpt": "Практический разбор synthetic hand-off: как отделить входные данные от вывода, остановить усиленный claim и передать следующему владельцу проверяемую границу риска.",
"contentHtml": "<p>Получатель открывает карточку и видит знакомые слова: evidence, decision, residual risk, next action. Через час он ищет ADR, метрику, тест и запись rollout, которых никогда не было. Ошибка началась не в коде. В документе сценарий выглядел как отчёт о выполненной работе. Цена — потерянное время, неверная операционная память и решение, принятое на основании отсутствующих данных.</p>\n<p>Есть и более тихий симптом. Автор называет synthetic hand-off «field report», добавляет правдоподобную дату, имя команды или номер изменения. Читатель уже не различает учебный literal и наблюдение из production. В следующем пересказе оговорка исчезает, а выдуманный результат остаётся. Поэтому такой текст должен начинаться не с красивого итога, а с границы: какие входы существуют, чего в них нет и какой вывод разрешён.</p>\n<p>Тезис простой: безопасная передача не доказывает результат. Она передаёт фиксированный сценарий, его происхождение, допустимую силу утверждения и явный путь остановки. Если вход имеет статус <code>scenario-only</code>, claim не может стать <code>benchmark-confirmed</code>. Если результат не наблюдался, его нельзя назвать выполненным. Это правило одинаково полезно для редакционного примера, архитектурной записки и будущего hand-off между командами.</p>\n<h2>Сначала отделите наблюдение от модели</h2>\n<p>Наблюдение отвечает на вопрос «что произошло и откуда это известно». Модель отвечает на вопрос «как можно организовать будущую проверку». Эти вопросы нельзя закрыть одной карточкой. В synthetic case есть фиксированный объект в памяти: его имя, дата плана, дата отсечения источников, варианты, отклонённый вариант, состояние evidence и residual risk. У объекта нет системы, пользователя, change или telemetry.</p>\n<p>В этом различии важен не английский словарь, а сила claim. <code>no-observation</code> говорит, что наблюдение не собрано. <code>scenario-only</code> говорит, что вход — учебная конструкция. <code>external-effect-none</code> говорит, что внешний эффект не запускался. Вместе эти поля не делают сценарий слабым. Они не дают ему притвориться сильнее, чем он есть.</p>\n<pre><code>const handoff = { caseName: 'named-fixed-synthetic-portfolio-case', plan-date: '2026-12', source-cutoff: '2026-07-31', evidence: { inputStrength: 'scenario-only', claimStrength: 'scenario-only', state: 'no-observation' }, requestedResult: 'bounded-hand-off', externalEffect: 'external-effect-none' };</code></pre>\n<p>Это учебный объект. Он не взят из production и не описывает выполненный проект. Его смысл — удержать границу между данными и выводом. Поля <code>plan-date</code> и <code>source-cutoff</code> задают время сценария, но не утверждают, что в декабре шла работа. Поле <code>requestedResult</code> описывает допустимый ответ функции, а не полезность решения для пользователя.</p>\n<h2>Варианты защищают от удобной легенды</h2>\n<p>Одновариантный рассказ почти всегда выглядит убедительно. Автор показывает выбранную структуру и не говорит, что могло быть иначе. В результате читатель принимает отсутствие альтернативы за качество решения. В фиксированном сценарии есть два имени: <code>narrow-evidence-note</code> и <code>expanded-evidence-note</code>. Первый сохраняет только границу входа и следующий вопрос. Второй добавил бы детали, похожие на реальные доказательства. В literal явно указан <code>rejectedOption</code>.</p>\n<p>Отклонённый вариант не означает, что состоялся design review. Он нужен как контроль потери контекста. Если поле пустое, evaluator возвращает <code>stop-missing-rejected-option</code>. Он не выбирает вариант сам и не дописывает причину отказа. Такой отрицательный путь полезнее автоматического значения по умолчанию: он возвращает проблему туда, где исчезло решение.</p>\n<p>То же правило действует для дат и источников. Если сценарий теряет <code>plan-date</code> или меняет cutoff, evaluator возвращает <code>stop-undated-scenario-or-cutoff</code>. Дата не превращает модель в исторический факт. Она лишь не даёт пересказать сценарий как нечто вне времени.</p>\n<figure><img src=\"/assets/editorial/2026/portfolio-case-2026-evidence-boundary-loop.svg\" alt=\"Схема проверки границы synthetic hand-off: карточка проходит проверки даты, вариантов и силы evidence, а усиленный claim возвращается в stop\" loading=\"lazy\" /><figcaption>Иллюстрация показывает маршрут статусов synthetic hand-off. Она не показывает реальный workflow, запуск, изменение системы или production-результат.</figcaption></figure>\n<h2>Симптом → причина → проверка → действие</h2>\n<div class=\"table-scroll\"><table><caption>Проверки границы для безопасной передачи</caption><thead><tr><th scope=\"col\">Симптом</th><th scope=\"col\">Причина</th><th scope=\"col\">Проверка</th><th scope=\"col\">Действие</th></tr></thead><tbody><tr><td>В карточке есть положительный результат, но вход только scenario-only</td><td>Claim сильнее исходных данных</td><td>Сравнить inputStrength и claimStrength</td><td>Вернуть stop и снизить claim до scenario-only</td></tr><tr><td>Указан один вариант</td><td>Отсутствует rejected option</td><td>Проверить минимум два options и имя отвергнутого варианта</td><td>Остановить передачу и восстановить границу выбора</td></tr><tr><td>Нет даты плана или cutoff</td><td>Сценарий потерял временную рамку</td><td>Сверить plan-date 2026-12 и source-cutoff 2026-07-31</td><td>Вернуть stop-undated-scenario-or-cutoff</td></tr><tr><td>В тексте появились ADR, metric или rollout</td><td>Модель получила неразрешённые production-поверхности</td><td>Найти утверждения о сделанном и источник каждого</td><td>Удалить claim или заменить его на допустимый вопрос</td></tr><tr><td>Положительный status запускает внешнее действие</td><td>Hand-off перепутан с очередью работ</td><td>Проверить externalEffect и наличие вызовов наружу</td><td>Оставить только in-memory результат с external-effect-none</td></tr></tbody></table></div>\n<h2>Как работает fail-closed проверка</h2>\n<p>Проверка должна принимать только известный fixed literal. Произвольный объект с похожими полями недостаточен: он может содержать незаметно усиленный claim. Поэтому evaluator сначала сравнивает вход с одним из именованных сценариев. Затем он проверяет дату, варианты, состояние evidence и запрошенный результат. Ошибка на любом шаге возвращает статус stop, причину и следующий безопасный шаг.</p>\n<p>Порядок важен. Сначала проверяется provenance объекта, потом сила его утверждения. Нельзя обсуждать качество решения, если неизвестно, откуда взялся вход. Нельзя обсуждать rollout, если результат уже запрещён самим контрактом. Короткий ответ с причиной лучше длинного текста, который компенсирует пропущенное поле правдоподобной историей.</p>\n<pre><code>const incompleteStory = prepareHandoff('missing-rejected-option-v1'); const reply = gateHandoff(incompleteStory); console.log({ status: reply.status, action: reply.nextAction, production: reply.externalEffect }); // status: stop-missing-rejected-option; action: name-the-option-not-carried-forward; production: external-effect-none</code></pre>\n<p>Фрагмент учебный. Он вызывает функции из локального модуля, не читает файлы и не делает сетевых запросов. Его вывод показывает классификацию неполного literal. Он не подтверждает качество архитектуры, не создаёт ADR и не доказывает, что подобный сценарий случался в рабочей системе.</p>\n<p>Ветвь с более сильным evidence должна завершаться так же жёстко. Если <code>inputStrength</code> равен <code>scenario-only</code>, а <code>claimStrength</code> равен <code>benchmark-confirmed</code>, результат — <code>stop-evidence-stronger-than-input</code>. Если запрошен <code>case-complete</code>, evaluator возвращает <code>stop-disallowed-positive-result</code>. В обоих случаях следующий шаг описывает исправление boundary, а не назначает владельца и не запускает работу.</p>\n<h2>Provenance — это не выдуманный audit trail</h2>\n<p>Для synthetic hand-off достаточно короткого происхождения: имя fixed case, дата плана, cutoff, набор вариантов и состояние <code>no-observation</code>. JSON clone отделяет выданный экземпляр от исходной константы. Deep freeze не даёт учебному вызову изменить вложенные поля в памяти. Эти свойства делают модель читаемой. Они не создают историю событий.</p>\n<p>Не добавляйте номер инцидента, ссылку на dashboard, имя реального владельца, timestamp якобы запуска или процент улучшения. Без источника такие детали не увеличивают воспроизводимость. Они только создают поверхность для ложной ссылки. Если цифра важна, сначала нужен разрешённый источник и метод измерения. До этого корректнее записать «не собрано» или «нельзя утверждать».</p>\n<p>Риск тоже надо формулировать точно. <code>future-owner-may-need-a-separate-evidence-contract</code> — это открытое условие. Оно не означает, что владелец уже назначен, контракт согласован или данные будут доступны. Следующий читатель может остановиться, запросить полномочия или отказаться от отдельного исследования. Материал должен позволять эти решения, а не подталкивать к ним скрытым обещанием.</p>\n<h2>Hand-off не равен очереди работ</h2>\n<p>Фраза «владелец подготовит ADR» уже утверждает владельца и будущий артефакт. Фраза «после change проверим метрику» утверждает change и набор метрик. В fixed input этого нет. Поэтому <code>nextAction</code> должен называть класс будущего вопроса: «уточнить, нужен ли отдельный evidence contract». Он не должен содержать назначение, дедлайн, уведомление или запуск.</p>\n<p>Техническая возможность также не равна разрешению. Модуль мог бы получить file reader, API client или доступ к telemetry. Это не даёт права читать production данные. Аналогично, команда могла бы написать тест, но модель не может заявить, что тест нужен, согласован или уже запущен. Граница hand-off — возвращаемый объект в памяти. Он не меняет систему и не отправляет сообщение наружу.</p>\n<h2>Порядок действий</h2>\n<ol><li>Назвать материал synthetic-сценарием и указать plan-date 2026-12 и source-cutoff 2026-07-31.</li><li>Выбрать только именованный fixed literal. Не принимать объект с похожей формой из неизвестного источника.</li><li>Проверить контекст и записать минимум два варианта. Явно назвать rejected option.</li><li>Оставить evidence как scenario-only, claim как scenario-only, а state как no-observation.</li><li>Проверить, что в тексте нет утверждений о реальном ADR, benchmark, metric, test, incident, change, rollout или результате.</li><li>Отклонить любой requested result, кроме bounded-hand-off с externalEffect: external-effect-none.</li><li>Вернуть status, reason, boundary, residual risk и nextAction без внешних вызовов.</li><li>Передать карточку следующему читателю как ограниченный вопрос, а не как поручение и не как подтверждение.</li></ol>\n<h2>Ограничения и отрицательный путь</h2>\n<p>Такая модель не заменяет реальный evidence hand-off. Она не проверяет качество будущего решения, совместимость вариантов, безопасность изменения или пользу для пользователя. В ней нет production inputs, контрольной группы, периода наблюдения, измерительного плана и разрешения на внешнее действие. Нельзя использовать её как аргумент для release decision, security review или архитектурного утверждения.</p>\n<p>Отрицательный путь не означает, что система сломалась. Он означает, что вход не позволяет сделать следующий вывод. Отсутствующий rejected option возвращает вопрос о выборе. Усиленный claim возвращает вопрос о доказательстве. Недатированный сценарий возвращает вопрос о границе времени. Запрещённый positive result возвращает материал к hand-off. Это полезная остановка: она сохраняет неопределённость видимой и не заполняет её выдуманными фактами.</p>\n<p>Есть и практическое ограничение формата. Короткая карточка может потерять детали при пересказе. Поэтому рядом с полями нужно хранить boundary и reason, а не только status. Статус без объяснения быстро превращается в зелёную галочку. Причина удерживает связь между конкретным нарушением и действием, которое допустимо дальше.</p>\n<h2>Критерий готовности</h2>\n<p>Передача готова, если читатель за один проход может назвать источник входа, временную рамку, два варианта, отвергнутый вариант, силу evidence, состояние наблюдения и residual risk. Для каждого усиленного claim существует явный stop. Успешный status не обещает production effect и возвращает только bounded-hand-off. Учебный код помечен как учебный, иллюстрация имеет существующий asset path, а ссылки отделены от собственных данных модели.</p>\n<p>Готовность не равна фразе «кейс доказан». Здесь проверяемый итог скромнее: граница не потерялась при hand-off, отрицательный путь различим, а следующий читатель понимает, что ещё нужно получить до любого реального решения. Если хотя бы одно из этих условий нарушено, документ следует остановить и исправить, а не украшать дополнительными деталями.</p>\n<h2>Проверяемые источники</h2>\n<ul><li><a href=\"https://csrc.nist.gov/pubs/sp/800/30/r1/final\" target=\"_blank\" rel=\"noopener noreferrer\">NIST SP 800-30 Rev. 1: Guide for Conducting Risk Assessments</a> — официальный документ для терминов risk assessment и residual risk. Он не подтверждает этот synthetic case и не заменяет собственные входы.</li><li><a href=\"https://www.rfc-editor.org/rfc/rfc8174\" target=\"_blank\" rel=\"noopener noreferrer\">RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</a> — официальный RFC о точном применении нормативных ключевых слов. Он не назначает владельца, не разрешает change и не превращает synthetic status в факт эксплуатации.</li></ul>"
}