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

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": 110,
"slug": "editorial-2024-12-mechanism-maintenance-retro",
"title": "Как приоритизировать сопровождение без ложной точности",
"excerpt": "Maintenance backlog становится полезным, когда отделяет наблюдаемый факт от оценки. Разбираем evidence, повторяемость и uncertainty, чтобы выбрать следующую проверку и не принять учебный score за прогноз.",
"contentHtml": "<p>В maintenance backlog появляется строка «риск 8,7», но никто не может показать исходные данные. В соседней карточке зафиксирован один и тот же симптом после нескольких проверок, но числового score нет. Команда выбирает первую задачу: число выглядит точнее. Цена ошибки — повторяемый дефект остаётся без проверки, а спорная оценка получает вид готового решения. Позже приходится восстанавливать границу риска, владельца и основание приоритета.</p><p><strong>Тезис:</strong> сопровождение нужно приоритизировать по проверяемой границе, а не по красивой арифметике. Сначала отделите evidence от оценки, repeatability от впечатления, а uncertainty от нулевого риска. Затем используйте score только как фильтр очереди. Он может выбрать следующую проверку, но не доказывает вероятность сбоя, денежную экономию или необходимость изменения.</p><h2>Механизм: факт, сигнал, граница действия</h2><p><code>Evidence</code> — факт, который можно предъявить другому инженеру: запись проверки, contract, тест, runbook или повторная карточка. <code>Signal</code> — признак, помогающий выбрать следующий вопрос. <code>Priority boundary</code> — правило, которое переводит карточку в одно из состояний: проверить сейчас, подготовить к следующему review или наблюдать. Эти понятия нельзя заменять одним числом.</p><p>Для каждого item нужны четыре поля. Первое — symptom: что наблюдаем и где. Второе — boundary: какой потребитель, интерфейс или операция затронуты. Третье — evidence: что уже известно и чего нет. Четвёртое — action: какую одну проверку можно выполнить без расширения scope. Добавьте unknown и stop condition: они сохраняют пробел в знаниях и запрещают незаметно превратить диагностику в rewrite. Если action требует сначала узнать владельца, собрать неизвестный граф зависимостей и изменить код, карточка описывает не задачу, а гипотезу.</p><p>Повторяемость тоже имеет границу. Можно считать повтором только тот же diagnostic step, тот же вопрос совместимости или тот же recheck gate. Фразы «мы часто к этому возвращаемся» недостаточно. Если boundary меняется от review к review, события нельзя складывать в один показатель.</p><figure><img src='/assets/editorial/2024/maintenance-retro-2024-debt-risk-heatmap.svg' alt='Учебная heatmap сопоставляет impact и repeatability, а uncertainty показывает отдельную границу проверки' loading='lazy' /><figcaption>Учебная heatmap помогает расположить карточки по двум осям. Она задаёт порядок review, но не показывает вероятность отказа и не считает бюджет.</figcaption></figure><h2>Какие evidence нельзя смешивать</h2><table><caption>Тип evidence и допустимый вывод</caption><thead><tr><th scope='col'>Тип</th><th scope='col'>Что зафиксировано</th><th scope='col'>Чего это не доказывает</th><th scope='col'>Следующий вопрос</th></tr></thead><tbody><tr><td>Known artifact</td><td>Есть конкретный тест, contract, runbook или запись проверки</td><td>Что artifact покрывает всех потребителей и все пути</td><td>Какую именно границу он покрывает?</td></tr><tr><td>Leading signal</td><td>До изменения виден ранний признак роста риска или scope</td><td>Что отказ уже произошёл или обязательно произойдёт</td><td>Какой stop condition сработает раньше?</td></tr><tr><td>Lagging signal</td><td>Один и тот же вопрос вернулся после review</td><td>Что известна первопричина или будущая частота</td><td>Что прошлое действие не изменило?</td></tr><tr><td>Unknown</td><td>Данных недостаточно или метод проверки недоступен</td><td>Что риск равен нулю и число можно угадать</td><td>Какой разрешённый метод изменит статус?</td></tr></tbody></table><p>Known artifact сужает область незнания, но не закрывает её автоматически. Leading signal позволяет остановить расширение scope до изменения системы. Lagging signal показывает повторение, но не объясняет причину. Unknown — не пустая клетка. Это явное условие, при котором нельзя усиливать вывод.</p><p>Такой подход согласуется с практикой оценки риска: оценка помогает выбрать курс действий, но не заменяет решение владельца. Если неизвестное исчезает при переносе строки в таблицу, формула начинает работать с ложным входом. Сначала сохраните текст неизвестного. Потом решайте, нужен ли отдельный способ его проверить.</p><h2>Что можно измерять без фальшивой цены</h2><p>У maintenance item бывает наблюдаемый класс издержки: повторное ручное объяснение, задержка review, дополнительная проверка, возврат к той же границе. Такой label честнее, чем «экономия 14 часов», если команда не зафиксировала период, выборку, метод подсчёта и право использовать эти данные.</p><p>Денежная оценка требует отдельного контракта. Нужны scope, период, источник, правило attribution и человек, который принимает допущения. Без них точное число создаёт асимметрию: карточка с выдуманной суммой выигрывает у карточки с честным unknown. Для порядка review достаточно сказать, какой повторяемый шаг мешает работе и как его можно проверить.</p><p>Перед расчётом зафиксируйте шкалу. Например, impact и repeatability можно задавать значениями от 1 до 3, uncertainty — от 1 до 3, а evidenceStrength — от 0 до 3. Для каждого значения заранее запишите границу и источник. Если источник отсутствует, оставьте unknown, а не подставляйте ноль.</p><h2>Учебная формула и воспроизводимый запуск</h2><p>Ниже — учебный пример. Он работает только с заранее заданными метками impact, repeatability, uncertainty и evidenceStrength. Он не читает production-метрики, не использует историю инцидентов и не предсказывает результат. Сохраните JavaScript в файл <code>priority-demo.mjs</code>, а затем выполните команду из каталога с этим файлом:</p><pre><code>node priority-demo.mjs</code></pre><pre><code>function teachingPriority(card) {\n const score = card.impact * card.repeatability\n + card.uncertainty * 2\n - card.evidenceStrength;\n\n const boundary = score &gt;= 10\n ? 'review-now'\n : score &gt;= 6\n ? 'plan-next-review'\n : 'watch-and-recheck';\n\n return { score, boundary };\n}\n\n// Учебный объект в памяти. Не production-метрика.\nconst example = teachingPriority({\n impact: 3,\n repeatability: 2,\n uncertainty: 2,\n evidenceStrength: 1,\n});\nconsole.log(example);\n// { score: 9, boundary: 'plan-next-review' }</code></pre><p>Число 9 в этом фрагменте ничего не говорит о вероятности сбоя. Оно только показывает, как выбранные teaching labels переводят карточку в учебную полосу. Если reviewer не согласен с uncertainty или evidenceStrength, спорить нужно с входом и его границей, а не с десятичными знаками.</p><p>В реальном проекте такой score можно применять только после явного согласования шкал и источников. Если у карточки появился traffic, incident count или денежная оценка, это не повод молча добавить поле в объект. Нужно пересмотреть модель и правила доступа к данным. Иначе учебная функция начинает изображать систему, которой она не видела.</p><h2>Симптом → причина → проверка → действие</h2><table><caption>Диагностика maintenance-приоритета</caption><thead><tr><th scope='col'>Симптом</th><th scope='col'>Причина</th><th scope='col'>Проверка</th><th scope='col'>Действие</th></tr></thead><tbody><tr><td>Карточка с высоким score не имеет факта</td><td>Оценку приняли за evidence</td><td>Попросить ссылку на тест, контракт, incident или повторную запись</td><td>Понизить вывод до unknown и назначить отдельную проверку</td></tr><tr><td>Один симптом возвращается на каждом review</td><td>Повторяемая граница не названа</td><td>Сравнить diagnostic step, consumer и recheck gate</td><td>Сформулировать одну bounded проверку, не начинать rewrite</td></tr><tr><td>Unknown исчез после расчёта</td><td>Пропуск данных заменили нулём</td><td>Сверить исходную карточку и обязательные поля модели</td><td>Остановить score и сохранить причину неизвестности</td></tr><tr><td>Leading signal требует немедленного deploy</td><td>Ранний признак перепутали с доказанным отказом</td><td>Проверить symptom, affected boundary и stop condition</td><td>Ограничить следующий шаг review или тестом</td></tr><tr><td>Lagging signal лечат автоматизацией</td><td>Повторение приняли за первопричину</td><td>Открыть прошлую карточку и проверить, что изменилось</td><td>Сначала уточнить owner, evidence и действие, затем выбирать автоматизацию</td></tr><tr><td>Денежная сумма определяет очередь</td><td>Нет периода, метода или attribution</td><td>Проверить источник, выборку, допущения и полномочия</td><td>Вернуть cost к наблюдаемому классу до отдельной оценки</td></tr></tbody></table><h2>Отрицательный путь важнее красивого score</h2><p>Проверка должна уметь остановиться. Если карточка не содержит boundary, owner role или evidence, результатом не должен быть score с нулевыми значениями. Ноль означает измеренное отсутствие, а unknown означает отсутствие знания. Эти состояния нельзя смешивать.</p><p>Остановите draft, если scope вырос с одной проверки до переписывания подсистемы, если action не имеет stop condition или если неизвестный consumer влияет на решение. Не объявляйте item закрытым после одной удачной проверки. Успешный путь показывает, что выбранный вход обработан. Отрицательный путь показывает, что опасный вход не превратился в разрешение на изменение.</p><p>Для lagging signal отдельно сравните прошлое и текущее действие. Если symptom вернулся, спросите, изменился ли contract, owner, evidence или stop condition. Если ничего не изменилось, повторная формулировка задачи не является прогрессом. Если изменилось только название, карточку нужно вернуть в review.</p><h2>Порядок работы</h2><ol><li><strong>Опишите symptom.</strong> Укажите наблюдаемый факт, место и цену ошибки без предположения о причине.</li><li><strong>Назовите boundary.</strong> Зафиксируйте consumer, интерфейс, диагностический шаг или recheck gate.</li><li><strong>Разделите evidence.</strong> Отметьте known artifact, leading signal, lagging signal и unknown отдельно.</li><li><strong>Выберите один action.</strong> Он должен проверять границу и иметь stop condition без изменения production.</li><li><strong>Назначьте повторяемость.</strong> Считайте повтором только одинаковый diagnostic step или тот же recheck gate.</li><li><strong>Проверьте score.</strong> Если применяете учебную шкалу, покажите все входы и не называйте результат вероятностью или ценой.</li><li><strong>Передайте decision owner.</strong> Он выбирает review-now, plan-next-review или watch-and-recheck с учётом остаточного риска.</li><li><strong>Зафиксируйте результат.</strong> Запишите, какое знание изменилось, какой путь остановился и что проверять при следующем review.</li></ol><h2>Ограничения применимости</h2><p>Heatmap и формула не заменяют risk assessment, change approval, тесты, rollback и наблюдение системы. Они не знают реальный traffic, SLO, support queue, стоимость простоя или число пользователей. Учебный код не подключается к данным и не подтверждает, что выбранные коэффициенты подходят вашему проекту.</p><p>Preventive maintenance не всегда нужно автоматизировать. Ручной review может быть обязательным из-за безопасности, прав доступа или редкой операции. Повторяемость сама по себе не доказывает, что автоматизация окупится. Она только помогает найти шаг, который стоит разобрать.</p><p>Нельзя выдавать score за вероятность incident. Нельзя считать отсутствие evidence доказательством отсутствия риска. Нельзя включать реальный incident или денежную оценку в учебную модель без нового контракта, метода и ответственного владельца. При такой неопределённости правильное действие — остановить расширение scope.</p><h2>Проверяемый критерий готовности</h2><p>Карточка готова к следующему review, если другой инженер может восстановить symptom, boundary, тип сигнала, evidence, неизвестное, один action и stop condition. Для каждого значения понятно, откуда оно взялось. Для каждого перехода между полосами понятна причина. Повторная проверка на том же входе даёт тот же статус.</p><p>Если используется score, рядом лежат шкала, формула и явная оговорка о её учебном или локальном статусе. Отрицательная проверка переводит карточку в hold или unknown, а не в нулевой риск. Готовность означает не «задача решена», а «следующий шаг ограничен, проверяем и не маскирует неизвестное».</p><h2>Проверяемые источники</h2><ul><li><a href='https://sre.google/sre-book/postmortem-culture/' target='_blank' rel='noopener noreferrer'>Google SRE Book: Postmortem Culture</a> — официальный материал о фиксации влияния, причин и follow-up. Он не задаёт универсальный score для maintenance backlog.</li><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> — официальное руководство по контексту, неопределённости и использованию оценки риска для выбора действий. Оно не подтверждает учебную формулу и не превращает баллы в вероятность.</li><li><a href='https://sre.google/sre-book/eliminating-toil/' target='_blank' rel='noopener noreferrer'>Google SRE Book: Eliminating Toil</a> — официальный материал о повторяемой ручной работе и её инженерной ценности. Он не доказывает окупаемость автоматизации для конкретной системы.</li></ul>"
}