Files
progcode/editorial/agent-rewrites/077.json
T

8 lines
23 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": 77,
"slug": "editorial-2025-11-mechanism-research-method",
"title": "Как проверить источник до того, как он повлияет на решение",
"excerpt": "Дата, версия, HTTP-валидатор и цифровая подпись отвечают на разные вопросы. Разбираем, как связать источник с наблюдаемым фактом, не расширить его смысл и остановить неподтверждённое решение.",
"contentHtml": "<p>Команда находит страницу с нужным API и сразу переносит совет в интеграцию. В адресе есть знакомый номер, в ответе — <code>ETag</code>, внизу — свежая дата. Через месяц обновлённый endpoint ведёт себя иначе: номер был частью адреса документа, а <code>ETag</code> оказался валидатором представления, а не номером релиза. Ошибка уже превратилась в код, обходы и спор о том, какую страницу читали.</p>\n<p>Источник полезен только тогда, когда понятно, что именно он подтверждает. Для инженерного решения нужно разделить публикацию, конкретное представление, наблюдение, утверждение и действие. У каждого уровня своя граница. Если версия, локатор или область применимости неизвестны, правильный результат проверки — остановка и точное описание недостающего факта.</p>\n<h2>Источник не равен доказательству</h2>\n<p>Начинайте с формулировки решения, которое может измениться. «Документация про кеш» слишком широко. «Для GET-запроса к ресурсу X можно повторить условный запрос, если сервер прислал тот же валидатор» уже указывает объект, метод и условие. Теперь ясно, какой факт искать и какой результат нельзя обещать без отдельного теста.</p>\n<p>Полезно различать пять уровней:</p>\n<ul><li><strong>Публикация</strong> — RFC, спецификация, релиз или страница владельца продукта.</li><li><strong>Представление</strong> — конкретный HTML, PDF, commit или HTTP-ответ, который был прочитан.</li><li><strong>Наблюдение</strong> — короткий фрагмент, видимый в этом представлении: раздел, строка, поле или заголовок.</li><li><strong>Утверждение</strong> — вывод о нашем объекте, версии и режиме работы.</li><li><strong>Решение</strong> — изменение кода, конфигурации, теста или процесса.</li></ul>\n<p>RFC может подтвердить смысл поля протокола, но не совместимость нашего SDK. Commit может подтвердить содержимое файла, но не успешность запуска в другой среде. Отчёт теста может подтвердить один сценарий, но не «работает всегда». Скачок от наблюдения к решению и есть место, где чаще всего появляется лишняя уверенность.</p>\n<figure><img src=\"/assets/editorial/2025/research-method-2025-claim-status-matrix.svg\" alt=\"Матрица проверки источника: наличие версии и наблюдаемого артефакта переводит утверждение в ограниченный статус, а слишком широкий вывод останавливается\" loading=\"lazy\" /><figcaption>Сначала закрепляем представление и читаемый артефакт, затем ограничиваем утверждение областью применения. Статус выбирает следующее действие, а не оценивает авторитет сайта.</figcaption></figure>\n<h2>Что на самом деле показывают дата и ETag</h2>\n<p>HTTP передаёт не сам ресурс, а его представление — данные и метаданные, выбранные для конкретного запроса. Поэтому один URL может давать разные представления из-за языка, формата, кодировки или других условий согласования. В RFC 9110 поле <code>ETag</code> определено как непрозрачный валидатор выбранного представления. Сервер сам выбирает способ его формирования; клиенту нужно сравнивать значение по правилам HTTP, а не расшифровывать его.</p>\n<p>Из <code>ETag: \"8.1\"</code> нельзя заключить, что перед нами релиз 8.1, документ опубликован в августе или другой endpoint поддерживает тот же контракт. Это может быть хеш, внутренний идентификатор или другое значение, различающее представления. Слабый валидатор с префиксом <code>W/</code> дополнительно имеет иные правила сравнения.</p>\n<p><code>Last-Modified</code> сообщает дату последнего изменения представления в смысле HTTP-валидатора. Она не обязана совпадать с датой выпуска продукта, датой утверждения API или временем, когда команда впервые прочитала документ. Заголовок <code>Vary</code> может указать, какие поля запроса участвуют в выборе представления. Ни один из этих заголовков не заменяет pin релиза, commit или датированный документ.</p>\n<p>Практическая запись должна хранить их раздельно:</p>\n<pre><code>sourceUrl: https://api.example.test/docs\nsourcePin: vendor-api-2.4.1\nlocator: \"GET /reports, section Conditional requests\"\nobservedAt: 2025-11-15T10:00:00Z\netag: \"8.1\"\nlastModified: Sat, 15 Nov 2025 10:00:00 GMT</code></pre>\n<p>Значения в примере учебные. <code>sourcePin</code> отвечает на вопрос «какую версию документа закрепили», а <code>etag</code> — «какой валидатор сообщил сервер для выбранного представления». Сохранять оба полезно, но подменять одно другим нельзя.</p>\n<h2>Целостность документа и смысл утверждения</h2>\n<p>Цифровая подпись решает криптографическую задачу: при корректной проверке она даёт сведения о происхождении и целостности подписанных данных, а также поддерживает неотказуемость подписанта в заданной инфраструктуре. Это не означает, что каждый тезис документа подходит нашему продукту или что авторский прогноз стал измеренным результатом.</p>\n<p>Например, подписанный файл может описывать старую версию, другой метод или условие, которого нет в нашей системе. Подпись защищает связь с конкретными данными; область применимости и смысл нужно проверять отдельно. У записи исследования поэтому должны быть как минимум две независимые строки: <code>integrity</code> и <code>claimEvidence</code>.</p>\n<p>Эту же границу помогает увидеть модель происхождения W3C PROV. В ней документ — сущность, чтение или преобразование — действие, а человек, сервис или программа — участник, связанный с ответственностью. Время, версия и связь между редакциями делают историю проверяемой. PROV описывает происхождение, но не выдаёт автоматический рейтинг качества и не доказывает деловую пригодность решения.</p>\n<h2>Воспроизводимый пример с отрицательной веткой</h2>\n<p>Ниже — самостоятельный скрипт без сети, базы данных и настоящей криптографии. Он проверяет только структуру записи и не притворяется проверкой внешнего мира. Сохраните фрагмент в файл <code>claim-check.mjs</code>, затем выполните команды:</p>\n<pre><code>node --version\nnode claim-check.mjs</code></pre>\n<pre><code>const record = {\n sourceUrl: 'https://www.rfc-editor.org/rfc/rfc9110.html#section-8.8.3',\n sourcePin: 'RFC 9110',\n locator: 'section 8.8.3',\n scope: 'HTTP response; selected representation',\n observation: 'ETag is an opaque validator for differentiating representations',\n claim: 'ETag is the software release number'\n};\n\nfunction assess(item) {\n const required = ['sourceUrl', 'sourcePin', 'locator', 'scope', 'observation', 'claim'];\n const missing = required.filter((field) =&gt; !item[field]);\n\n if (missing.length &gt; 0) {\n return { status: 'hold', reason: 'missing-field', missing };\n }\n\n if (item.claim === 'ETag is the software release number') {\n return { status: 'hold', reason: 'observation-does-not-support-claim' };\n }\n\n return { status: 'ready-for-scoped-use', reason: 'record-is-addressable' };\n}\n\nconsole.log(assess(record));\n// { status: 'hold', reason: 'observation-does-not-support-claim' }</code></pre>\n<p>На обычном Node.js скрипт напечатает отказ: запись адресуемая, но наблюдение говорит о валидаторе представления, а утверждение называет его номером релиза. Если заменить <code>claim</code> на «ETag различает представления в данном HTTP-контексте», локальная проверка пройдёт. Это всё ещё не доказывает поведение конкретного сервера: для него нужен отдельный запрос с зафиксированными входами.</p>\n<p>Отрицательная ветка важнее красивого статуса <code>ready</code>. Удалите <code>sourcePin</code>, измените метод или расширьте утверждение с одного ресурса на весь API — запись должна перейти в <code>hold</code> либо потребовать нового наблюдения. Список обязательных полей защищает журнал от пустой ссылки, но не превращает заполненную карточку в эксперимент.</p>\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>Номер RFC, релиз или commit</td><td>К какому закреплённому материалу относится цитата</td><td>Что система внедрила этот контракт</td><td>Сверить локатор и версию клиента/сервера</td></tr><tr><td><code>ETag</code></td><td>Валидатор выбранного HTTP-представления</td><td>Номер релиза и бизнес-смысл ресурса</td><td>Проверить условный запрос и правила сравнения</td></tr><tr><td><code>Last-Modified</code></td><td>Дату изменения представления по правилам HTTP</td><td>Дату выпуска продукта или дату утверждения API</td><td>Найти официальный release note или тег</td></tr><tr><td>Цифровая подпись</td><td>Целостность и происхождение подписанных данных при корректной проверке</td><td>Истинность каждого тезиса и совместимость с нашим кодом</td><td>Проверить scope, ключ, политику и независимый факт</td></tr><tr><td>Текущий URL</td><td>Куда можно перейти сейчас</td><td>Как выглядел документ в момент решения</td><td>Закрепить версию, commit, PDF или архивный снимок</td></tr><tr><td>Результат теста</td><td>Поведение в указанных входах и среде</td><td>Поведение во всех версиях, ролях и нагрузках</td><td>Повторить сценарий и перечислить ограничения</td></tr></tbody></table></div>\n<h2>Порядок проверки перед решением</h2>\n<ol><li><strong>Назовите действие.</strong> Запишите, что именно хотите изменить: метод, endpoint, зависимость, конфигурацию или текст инструкции.</li><li><strong>Ограничьте объект.</strong> Укажите версию, среду, права, метод HTTP, формат данных и другие признаки, от которых зависит результат.</li><li><strong>Выберите первичный источник.</strong> Для протокола используйте нормативный документ, для библиотеки — официальный релиз и документацию владельца, для кода — конкретный commit.</li><li><strong>Закрепите представление.</strong> Сохраните pin, дату чтения и, если это HTTP-ответ, безопасные для публикации заголовки. Текущий URL оставьте как навигацию.</li><li><strong>Запишите локатор.</strong> Это раздел RFC, страница PDF, путь к файлу, endpoint или точное поле. Ссылка на главную страницу недостаточна.</li><li><strong>Перепишите наблюдение без вывода.</strong> Оставьте то, что можно увидеть или повторить. Не заменяйте «сервер прислал ETag» фразой «версия совместима».</li><li><strong>Сопоставьте силу утверждения.</strong> Сверьте субъект, метод, версию и условие. Слова «всегда», «безопасно» и «для любого клиента» требуют отдельного доказательства.</li><li><strong>Проверьте отрицательный путь.</strong> Уберите pin, измените scope или подставьте другой режим. Проверка должна остановиться с понятной причиной, а не сохранить прежний совет.</li><li><strong>Выберите следующее действие.</strong> Это может быть scoped use, новый запрос, тест, запрос к владельцу документа или отказ от решения. Запишите критерий, по которому вернётесь к карточке.</li></ol>\n<h2>Когда нужно остановиться</h2>\n<p>Остановитесь, если документ нельзя однозначно закрепить, локатор ведёт в другой раздел, текущая страница изменилась, а исторического представления нет, или подпись относится не к тому файлу. Точно так же остановитесь, если в тексте есть только рекламное обещание, а решение требует измерения производительности, безопасности или совместимости.</p>\n<p>Не заменяйте остановку усреднённым баллом доверия. Две ссылки на разные версии не становятся сильнее от сложения. Подписанный документ другой области не подтверждает наш endpoint. Пустое поле «дата» не компенсируется свежим впечатлением от страницы. Полезный результат в таких случаях — список: какого факта не хватает, где его получить и какой вывод пока запрещён.</p>\n<h2>Ограничения применимости</h2>\n<p>Метод не делает интернет неизменяемым и не превращает ссылку в лабораторный результат. Он не измеряет задержку, не проверяет нагрузку, не выполняет цифровую подпись и не устанавливает, что конкретный сервис соблюдает документ. Для этого нужны реальные входы, разрешённая среда, измерительный инструмент и отдельный критерий успеха.</p>\n<p>RFC описывает семантику HTTP, но не знает, как владелец API строит ETag. NIST описывает свойства цифровой подписи, но не проверяет доверенную цепочку ключей в вашем проекте. W3C PROV задаёт vocabulary для происхождения, но не требует конкретного формата журнала и не решает конфликт двух корректных источников. Эти границы нужно переносить в карточку решения, а не прятать в примечании.</p>\n<p>Учебный скрипт намеренно не обращается к сети. Его зелёный результат означает лишь, что локальная запись заполнена и не содержит известного слишком сильного вывода. Перед изменением production-кода дополнительно проверьте конкретную версию, права, данные, обратимость и влияние на пользователей.</p>\n<h2>Критерий готовности</h2>\n<p>Запись готова к использованию, когда другой инженер может без устного пояснения открыть закреплённый источник, перейти к локатору, увидеть наблюдение, назвать область применения и воспроизвести следующий шаг. При изменении версии, метода или объекта проверка должна показать, почему старый вывод больше не действует.</p>\n<p>Минимальная форма результата выглядит так: «В RFC 9110, разделе 8.8.3, <code>ETag</code> назван непрозрачным валидатором выбранного представления. Для GET ресурса X в версии Y проверяем условный запрос. Это не доказывает номер релиза, совместимость записи или поведение другого endpoint». Такая формулировка уже не обещает лишнего и оставляет команде проверяемое действие.</p>\n<h2>Проверяемые источники</h2>\n<ul><li><a href=\"https://www.rfc-editor.org/rfc/rfc9110.html#section-3.2\" target=\"_blank\" rel=\"noopener noreferrer\">RFC 9110, раздел 3.2: Representations</a> — объясняет, что HTTP передаёт представления состояния ресурса, выбранные в контексте запроса.</li><li><a href=\"https://www.rfc-editor.org/rfc/rfc9110.html#section-8.8\" target=\"_blank\" rel=\"noopener noreferrer\">RFC 9110, раздел 8.8: Validator Fields</a> — описывает валидаторы, включая дату изменения и entity tag; <a href=\"https://www.rfc-editor.org/rfc/rfc9110.html#section-8.8.3\" target=\"_blank\" rel=\"noopener noreferrer\">раздел 8.8.3</a> определяет <code>ETag</code> как непрозрачный валидатор.</li><li><a href=\"https://csrc.nist.gov/glossary/term/digital_signature\" target=\"_blank\" rel=\"noopener noreferrer\">NIST CSRC: Digital signature</a> — фиксирует свойства цифровой подписи: аутентификацию происхождения, целостность данных и поддержку неотказуемости при корректной реализации.</li><li><a href=\"https://www.w3.org/TR/prov-primer/\" target=\"_blank\" rel=\"noopener noreferrer\">W3C PROV Model Primer</a> — вводит сущности, действия, участников, происхождение, редакции и время как элементы описания истории данных.</li></ul>"
}