Техническое письмо Почему документация устаревает и что с этим делать структурно
0%

Почему документация устаревает и что с этим делать структурно

Почему документация устаревает и что с этим делать структурно

В вики компании 4200 страниц. Поиск по слову «деплой» отдаёт семнадцать результатов: три инструкции противоречат друг другу, две ссылаются на Jenkins, которого нет с позапрошлого года, одна — самая точная — лежит в личном пространстве человека, уволившегося в марте. Никто не врал. Каждая страница в день написания была правдой.

Это нормальное состояние документации в организации старше трёх лет, и оно не лечится объявлением в общем канале. Предыдущие главы трека заканчивались абзацем про устаревание конкретного жанра; эта занимается самим устареванием — почему оно неизбежно, какие бывают виды расхождения, что с ними делают инженеры и как отличить настоящую поддержку от ритуала, который её имитирует.

Документ не «устаревает» — он расходится с системой, потому что у него нет механизма, сообщающего о расхождении. Поддержка — это не «регулярно перечитывать», а перевести конкретный текст на ступень выше по проверяемости: из прозы в датированную запись, из записи в проверяемое машиной, из проверяемого в порождаемое.

Устаревание — свойство конструкции, а не характера

Экономика простая и безнадёжная. Инженер, меняющий код, платит за обновление документа сразу: вспомнить, что тот существует; найти; понять, какой абзац теперь врёт; переписать; провести через ревью — от десяти минут до часа. Выгоду получает кто-то другой и не сегодня: дежурный в три часа ночи через полгода, новый коллега через год, соседняя команда, которую инженер даже не знает. Издержки локальны и немедленны, польза распределена и отложена — классическая экстерналия, и никакая дисциплина её не отменяет, она лишь на время смещает баланс за счёт добровольца, который потом выгорает или уходит.

Второе обстоятельство хуже первого: расхождение не производит сигнала. Сломанный код падает в тестах, сломанный конфиг — в деплое, сломанный документ не падает нигде и выглядит ровно так же уверенно, как в день написания. Единственный способ узнать, что абзац врёт, — выполнить написанное и обжечься. А обжёгшийся обычно не имеет прав, времени и уверенности чинить чужую страницу: он идёт в чат и получает ответ голосом. Знание уходит из текста в устный канал, страница остаётся врать следующему.

Ключевой здесь переход 2025 года. Потеря доверия дороже самой ошибки: читатель не знает, какие ещё разделы врут, и рационально обесценивает документ целиком. Одна неверная команда убивает страницу быстрее, чем десять неполных абзацев — и порождает дубль, потому что писать рядом дешевле, чем чинить чужое. Дубли не причина беспорядка, а его ускоритель: каждая новая копия обязана разойтись со всеми остальными.

Три вида расхождения, и лечатся они по-разному

Слово «устарела» склеивает три разные болезни; лекарства у них разные, а цена ошибки отличается на порядок.

Вид Что произошло Чем опасно Структурное лекарство
Ложь документ утверждает то, чего в системе больше нет читатель выполняет и ломает; худший вид исполняемость, генерация, учения
Дыра система приобрела поведение, которого нет в тексте читатель не находит и идёт в чат; тихая потеря времени поисковые логи, вопросы как сигнал, триггер на изменение
Дубль два текста об одном, оба частично верны читатель не знает, какому верить; чинят один из двух один факт — один дом, включение вместо копии, удаление

Ложь обнаруживается пострадавшим, дыра — молчанием, дубль — поиском. Отсюда следствие: сначала охотятся на ложь, а не на полноту. Команда, начинающая расчистку с «давайте всё допишем», увеличивает поверхность поддержки и через квартал имеет то же самое, только больше.

Отдельно про 2026 год: ассистенты и поиск на эмбеддингах подняли цену лжи. Раньше устаревшая страница ждала, пока на неё наткнутся; теперь она попадает в контекст ассистента и пересказывается уверенным тоном без даты и без пометки «проверялось в 2024» — индексируется всё, включая личное пространство уволившегося. Вывод не про технологию, а про гигиену: удаление и разметка недостоверного стали дешёвым способом поднять качество ответов, которые команда получает каждый день.

У каждого факта свой период полураспада

Типичная ошибка — складывать в один абзац факты, живущие с разной скоростью. Срок жизни абзаца равен сроку жизни самого быстрого факта в нём: одно число из конфига обесценивает пять строк точной прозы вокруг.

Класс факта Пример Живёт Где ему место
Инвариант домена деньги хранятся в минорных единицах; повтор по ключу идемпотентен годы проза, пишется руками
Решение в прошлом выбрали PostgreSQL вместо MongoDB в ноябре 2025 не устаревает: датировано ADR
Событие инцидент от 2026-03-04 и его причины не устаревает постмортем
Форма кода и API сигнатуры, поля, коды ошибок, флаги CLI недели генерация из схемы, док API
Числа конфигурации TTL, лимиты, размер пула, число реплик дни включение из конфигурации, не копия
Процедура в окружении шаги быстрого старта, команды раннбука недели–месяцы исполняемый текст в CI, руководства
Организация владелец, дежурство, канал, ответственный квартал: реорганизации каталог сервисов, CODEOWNERS
Планы и намерения «в следующем квартале переедем на v7» недели трекер задач, а не документ

Правило, которое отсюда следует, стоит целой методички: разделяйте текст по скорости изменения, а не по темам. Медленное («почему кеш вообще есть и что будет, если он отвалится») пишется прозой и живёт годами; быстрое («maxmemory 4gb») не пишется вовсе — включается из источника; датируемое превращается в запись решения; планы уезжают в трекер, где у них есть статус и владелец.

Мины замедленного действия в тексте

Есть формулировки, гарантирующие расхождение: их видно в чужом тексте за секунду, и это самая дешёвая правка на ревью.

Мина Почему обречена Чем заменить
«в настоящий момент», «сейчас» момент письма читателю неизвестен дата: «на 2026-05-14» — или убрать фразу совсем
«мы используем Kafka» описание состояния: ложь в день миграции «выбрали Kafka 2025-11-03, ADR-014»
«планируется в следующем квартале» план протухает молча и не вычёркивается никогда ссылка на тикет; статус живёт в трекере
«временное решение» без даты снятия живёт дольше постоянных «временно до 2026-09-01, снимает PLAT-812»
«TTL 24 часа», «четыре пода» число уже есть в конфиге и уже разошлось включение из файла конфигурации
«отвечает команда платформы» команды переименовываются и распадаются сервис в каталоге плюс CODEOWNERS
«новый сервис», «см. чат #platform» через год непонятно, какой новый; каналы переименовываются имена собственные и постоянные адреса
«обычно», «как правило», «рекомендуется» не проверяется и маскирует незнание число и условие; см. «Ясность»

Почти каждая замена текст не удлиняет, а укорачивает: долгоживущий текст короче недолговечного, потому что из него вычищено всё, что и так лежит в машине.

Разбор: один и тот же раздел до и после

Страница «Сервис заказов — как устроено» в вики, раздел про кеш. Так пишут почти все, и текст выглядит добросовестным.

## Кеширование

В настоящий момент мы используем Redis (6.2) для кеширования профилей пользователей.
Кластер состоит из трёх нод с sentinel, maxmemory 4gb, политика вытеснения allkeys-lru,
TTL профиля — 24 часа. Redis выбрали, потому что он быстрый и у команды уже была
экспертиза. Планируется переход на Redis 7 в следующем квартале. По всем вопросам —
команда платформы, чат #platform.

Что здесь не так — по существу, а не стилистически:

  1. В шести строках смешаны факты пяти классов изменчивости: инвариант (кеш нужен), форма инфраструктуры (три ноды, sentinel), числа конфигурации (4 ГБ, 24 часа), решение (почему Redis), план (переход на 7), организация (команда платформы). Срок жизни абзаца равен сроку жизни самого быстрого факта — примерно спринт.
  2. Числа скопированы из values.yaml: у факта теперь два дома, и в одном он неизбежно устареет. Проверить рассинхрон нечем — ни один тест не читает этот абзац.
  3. «Быстрый и была экспертиза» — имитация обоснования: нет альтернатив, нет отвергнутых вариантов, нет даты. «Планируется в следующем квартале» — от какой даты отсчитывать? Состоялся переход или отменён, фраза врёт в обоих случаях, и вычёркивать её никто не придёт.
  4. Главного нет вовсе: что будет с сервисом, если кеш недоступен, и чего в кеш класть нельзя. Именно это спросит дежурный в три часа ночи, и именно это не меняется годами.

Переписанная версия — тот же материал, разложенный по скорости изменения:

## Кеш профилей

Профиль читается на каждом шаге оформления заказа, поэтому лежит в кеше. Кеш не источник
истины: при полной недоступности кеша сервис отвечает из базы медленнее (p99 растёт
примерно втрое), но ошибок не отдаёт — это проверяется учением `cache-blackout` раз
в квартал, последнее прошло 2026-04-18. В кеш нельзя класть данные, требующие немедленной
инвалидации: инвалидация асинхронная, окно до 2 секунд.

Параметры кластера и TTL здесь не дублируются, они берутся из конфигурации:

<!-- [[[cog: таблица параметров из deploy/orders/values.yaml, вставляет CI ]]] -->
<!-- [[[end]]] -->

Почему Redis, а не кеш в процессе: ADR-014 от 2025-11-03, статус accepted.
Смена мажорной версии: PLAT-812.
Владелец: сервис orders-profile-cache в каталоге, дежурство @acme/orders-oncall.

Что изменилось механически, а не на вкус:

Кусок исходного абзаца Куда уехал Срок жизни после переезда
«Redis 6.2, три ноды, maxmemory, TTL» включение из values.yaml, проверяется cog --check в CI не может разойтись: сборка красная
«выбрали, потому что быстрый» ADR-014, датированная запись с альтернативами не устаревает по построению
«планируется переход» тикет PLAT-812 статус живёт там, где его меняют
«команда платформы, чат #platform» каталог сервисов и CODEOWNERS переживает реорганизацию
— (не было) поведение при отказе кеша, запрет на данные с немедленной инвалидацией годы: это инвариант

Проза стала короче и полезнее: в ней осталось только то, чего машина не знает. Это общее правило поддержки — человек пишет невыводимое, всё выводимое выводится.

Короткий второй пример того же приёма. Было: «Мы поддерживаем PostgreSQL 13 и выше и Python 3.9+» — фраза стареет тихо, версии в CI меняются, строка остаётся. Стало — таблица версий, порождаемая из матрицы сборки:

# .github/workflows/test.yml — единственный источник истины про «поддерживаем»
strategy:
  matrix:
    postgres: ["14", "15", "16"]   # 13 выведен из матрицы 2026-03-01
    python: ["3.11", "3.12", "3.13"]

Теперь «поддерживаем» означает «проверяем на каждом PR», и чтобы соврать в документации, надо сначала сломать сборку. Это и есть перевод факта на ступень выше — к лестнице и переходим.

Лестница проверяемости

Лестница проверяемости документа: пять уровней от прозы до генерации

Пять ступеней различаются одним параметром — кто и через сколько узнаёт о расхождении.

Ступень Механизм Кто сообщает Задержка Чего не ловит
1. Проза ничего обжёгшийся читатель, если дойдёт месяцы или никогда всё
2. Датировано owner, last_verified, review_by, баннер возраста читатель, осознанно сразу, но решение на нём саму ошибку: только сигнал недоверия
3. Линтеры ссылки, структура, термины, запрещённые слова CI минуты ложь по существу
4. Исполняемость doctest, прогон быстрого старта, контрактные тесты, учения CI и расписание минуты–неделя то, что не выражено кодом
5. Генерация справочник из схемы, таблица из конфигурации, --help никто: расхождение невозможно смысл: зачем и когда применять

Три наблюдения, ради которых эта лестница нужна.

Ступени 4 и 5 не заменяют 1 и 2, а освобождают их. Полностью сгенерированный документ нечитаем: в нём нет ответа на «зачем». Смысл — вынести наверх всё машинное и оставить прозе незаменимое; тогда прозы становится мало и её реально поддерживать руками.

Подъём на одну ступень — задача с оценкой, в отличие от «навести порядок в документации». «Вынести таблицу параметров кеша в генерацию» — четыре часа; «прогонять быстрый старт в CI» — день; «проставить владельцев из каталога» — два дня на раздел. Такие задачи проходят приоритизацию, а «переписать вики» не проходит никогда.

Ступень 2 недооценена. Она не чинит ошибку, но честно передаёт неопределённость: «последний раз проверялось 2026-02-14 на версии 2.1» экономит час отладки чужого устаревшего примера. Для текста, который выше поднять нечем (объяснение архитектуры, обзор домена), это потолок — и им надо пользоваться, а не делать вид, что документ вечен.

Один факт — один дом

Дубли — самая дешёвая в предотвращении и самая дорогая в лечении болезнь: копия стареет независимо, и через год у вас два частично верных текста без способа узнать, какой кусок верен в каком. Правило: у каждого факта ровно один дом, остальные места ссылаются или включают. Механизмы включения есть в любом стеке — они превращают копию в проекцию:

--8<-- "deploy/orders/values.yaml:cache-params"   # MkDocs + pymdown-extensions
# .. literalinclude:: ../../deploy/orders/values.yaml   # Sphinx: кусок по маркерам
#    :start-after: # cache-params-start

cog --check docs/**/*.md                                  # разошлось — сборка красная
terraform-docs markdown table --output-check ./modules/orders

Признак дубля, который стоит искать на ревью: один и тот же URL, порт, лимит или имя переменной в двух документах. Греп по репозиторию находит такие пары за минуту, и почти каждая из них — будущее расхождение. Побочный эффект правила «один дом» приятный: документы короче, связность выше — но ссылки тоже гниют, поэтому линтер ссылок обязателен, иначе вы обменяли дубли на битые переходы.

Владелец: «команда платформы» — это никто

Документ без владельца мёртв через квартал, и главный убийца — не лень, а реорганизация. Команды переименовываются, распадаются, сливаются; человек из шапки уходит в другой отдел. Момент потери владельца не замечает никто: текст продолжает выглядеть живым, просто больше нет никого, кто узнает о его лжи. Поэтому владельца привязывают не к человеку и не к названию команды, а к сущности, переживающей организационные изменения, — к сервису в каталоге: у сервиса меняется владеющая группа, и вся привязанная документация меняет владельца сама.

Модель читается так: у документа всегда есть сервис-хозяин, объявленные источники, из которых он выводится, проверки, которые его сторожат, и ссылки на записи решений. Всё, что не привязано к сервису, — сирота и первый кандидат на удаление. Такую модель даёт из коробки каталог разработчика: в Backstage документация лежит рядом с кодом, а владельца берёт из каталога сущностей — механика в треке платформенной инженерии. Без каталога тот же эффект дают CODEOWNERS, где владелец — группа, а не человек: человек уходит в отпуск, меняет проект и увольняется, группа переживает всё это.

# изменение документа требует ревью владеющей группы, а не «кого-нибудь»
/docs/runbooks/          @acme/orders-oncall
/docs/adr/               @acme/architects
/docs/architecture.md    @acme/orders-platform

Срок жизни: TTL вместо «ревью раз в год»

Ежегодное ревью документации не работает по той же причине, по которой не работает призыв обновлять её: это задача без адресата, без критерия готовности и без последствий. Работает явный срок жизни, объявленный в самом файле и обрабатываемый машиной.

---
title: "Раннбук: переключение платёжного шлюза"
service: payments-gateway        # ключ в каталоге, отсюда берётся владелец
genre: runbook
covers: ["services/gateway/**", "deploy/gateway/**"]   # за чем следит документ
last_verified: 2026-05-14        # проставляется прогоном или учением, не вручную
review_by: 2026-08-14            # раннбук — квартал, объяснение — год, ADR — никогда
on_expiry: banner                # banner | issue | archive
---

Три детали отличают работающий TTL от косметики. Срок зависит от жанра: у раннбука квартал, у обзора архитектуры год, у ADR срока нет вовсе — запись о прошлом не портится. Истечение имеет последствие в интерфейсе читателя — баннер «не проверялось 143 дня» на самой странице, а не строчка в отчёте, который смотрит один человек. И нормальный исход просрочки — архив: если владелец не готов потратить час на проверку, документ не нужен; это ответ, а не провал.

Календарь — слабый триггер, сильный — событие на пути изменения: правка публичного флага CLI требует ревью каталога docs/; закрытие инцидента заводит задачу на проверку раннбука; выход нового человека назначает ему первым PR правку руководства, по которому он заводился (у него единственного ещё нет проклятия знания — «Онбординг»). Реализуется путями в правилах ревью и хуками: git-хуки, тесты в CI.

Самая полезная механическая проверка — не срок, а разрыв между документом и кодом, за которым документ следит. Поле covers из шапки делает это вычислимым:

#!/usr/bin/env python3
"""Насколько код ушёл вперёд документа, который его описывает.

Сравнивает дату последнего коммита в документ с датой последнего коммита в пути
из поля covers. Сложность — O(D * P) вызовов git log (D документов, P путей
на документ); на репозитории в тысячи файлов это секунды, поэтому джоб еженедельный.
"""
import subprocess, sys
from datetime import datetime
import yaml  # pip install pyyaml

git = lambda *a: subprocess.run(["git", *a], capture_output=True, text=True,
                                check=True).stdout.strip()


def last_commit(pathspec: str) -> datetime | None:
    """Дата последнего коммита, затронувшего pathspec (None, если истории нет)."""
    out = git("log", "-1", "--format=%cI", "--", pathspec)
    return datetime.fromisoformat(out) if out else None


def front_matter(path: str) -> dict:
    text = open(path, encoding="utf-8").read()
    return yaml.safe_load(text.split("---", 2)[1]) or {} if text.startswith("---") else {}


def main(max_lag_days: int = 60) -> int:
    stale = []
    for doc in git("ls-files", "docs/**/*.md").split():
        meta = front_matter(doc)
        covers, doc_at = meta.get("covers") or [], last_commit(doc)
        if not covers:   # документ не объявил, за чем следит, — тоже дефект
            stale.append((doc, 10**6, "covers не объявлен"))
            continue
        code_at = max((c for p in covers if (c := last_commit(p))), default=None)
        if doc_at and code_at and (lag := (code_at - doc_at).days) > max_lag_days:
            stale.append((doc, lag, f"владелец {meta.get('service', '—')}"))

    for doc, lag, note in sorted(stale, key=lambda r: -r[1]):
        print(f"{doc}: отставание {lag} дн. ({note})")
    return 1 if stale else 0   # красный джоб: иначе отчёт никто не откроет


if __name__ == "__main__":
    sys.exit(main(int(sys.argv[1]) if len(sys.argv) > 1 else 60))

Отчёт не чинит документы — он превращает невидимое в список с именами владельцев, и разговор о поддержке перестаёт быть разговором о чувствах: «раннбук платежей отстаёт от кода на 210 дней» обсуждается иначе, чем «у нас плохая документация».

Удаление — первоклассная операция

Самый недооценённый инструмент поддержки — кнопка «удалить». Устаревший документ хуже отсутствующего: отсутствие честно отправляет читателя к коду или к человеку, а ложь тратит его время и добавляет ложной уверенности. Удаление при этом психологически тяжелее написания: кажется, что уничтожаешь чужой труд. Снимают страх проверяемые аргументы: текст остаётся в истории git; страница с нулевым трафиком за квартал не потеряет читателей, потому что их нет; удаляя дубликат, вы делаете оставшийся документ достовернее. Процедура — не мгновенное стирание, а короткий конвейер:

  1. Баннер «не поддерживается с 2026-05-14, актуальное — здесь» и снятие из навигации.
  2. 90 дней карантина: если пришёл человек и сказал «мне это нужно» — документ получает владельца и возвращается; если не пришёл никто — идёт дальше.
  3. Удаление с надгробием: страница-заглушка с редиректом на замену, чтобы старые ссылки в тикетах и чатах не приводили в пустоту.
  4. Вычистить из поиска и индекса ассистента — это отдельный шаг, про который забывают: «перенесли в архив» не значит «перестало находиться».

Крайний случай — документное банкротство: пространство настолько велико и недостоверно, что чинить дешевле с нуля. Приём тот же, что при банкротстве технического долга (см. «Технический долг»): старое целиком помечается «архив, не поддерживается», рядом заводится новое небольшое пространство с жёсткими правилами (владелец, TTL, проверки), и туда переносится только то, что кто-то попросил перенести. Спрос как фильтр работает лучше инвентаризации: за квартал запрашивают обычно 5–15% страниц, остальное можно спокойно похоронить.

Что не поддерживать — сознательное решение

Поддержка стоит денег, бюджет конечен, и попытка держать актуальным всё — верный способ не удержать ничего. Нужен явный портфельный выбор: какой документ на какой ступени лестницы стоит и какой сознательно оставлен гнить с честной пометкой.

Левый верхний угол — то, что меняется редко, но стоит дорого при ошибке: раннбук отказа, восстановление из бэкапа, переключение ЦОД. Проверять его в CI обычно нечем, механизм другой — учения: раз в квартал дежурный проходит документ по шагам на стенде, и дата прохождения становится last_verified (см. «Учения и хаос»). Правый нижний угол — кандидат на «не писать вовсе»: список флагов, меняющийся еженедельно и стоящий читателю минуту недоумения, дешевле отдать команде --help, чем поддерживать. А для того, что решено не поддерживать, есть честная пометка status: unmaintained, последняя проверка 2025-11: не капитуляция, а информация — читатель поймёт, что перед ним черновик из прошлого, и не потратит час, доверяя ему как справочнику.

Инвентаризация: с чего начинать, когда всё плохо

Расчистка проваливается, когда начинается с чтения всего подряд. Начинать надо с данных, собираемых скриптом за час: список страниц, дата последней правки, просмотры за квартал, владелец, входящие ссылки. Дальше — механический триаж, в котором почти нет места вкусу.

Три правила триажа, без которых он вырождается в бесконечное обсуждение. Первое: дубли схлопываются до принятия любых других решений — пока их два, любая работа делается дважды. Второе: не чините то, что можно удалить; удаление — самая дешёвая правка на странице. Третье: на одну страницу тратится не больше пяти минут; если за пять минут непонятно, кому она нужна, ответ уже получен.

Расчистка — проект с концом, а не образ жизни: неделя на инвентарь, две на триаж, дальше удаление и дубли, затем линтеры, и только потом подъём выживших по ступеням. Порядок не случаен — удаление уменьшает объём работы на всех следующих этапах. Обратный порядок, при котором команда начинает с красивого портала документации, даёт красивый портал устаревших страниц.

Метрики: как измерять здоровье документации

Метрики нужны не для отчёта, а чтобы разговор о поддержке опирался на числа; всё перечисленное собирается скриптами из git, CI и аналитики портала.

Метрика Как собрать Что означает
Доля страниц с живым владельцем сверка service/owner с каталогом сколько документов осиротело после реорганизаций
Медианный разрыв «код ушёл вперёд» скрипт выше по полю covers системное отставание текста от системы
Доля просроченных по review_by обход front matter долг, который команда назначила себе сама
Битые ссылки lychee в CI распад связности: симптом дублей и удалений без надгробий
Доля справочника, порождаемого генерацией статистика по каталогам сколько текста физически не может врать
Страницы с нулевым трафиком за квартал аналитика вики или портала список кандидатов на удаление
Поисковые запросы без переходов логи поиска дыры: люди ищут то, чего нет
Вопросы в чате с ответом «в доке вот тут» ручной подсчёт за неделю документ есть, но не находится: проблема навигации
Время до первого PR нового человека git плюс дата выхода интегральная проверка онбординг-документов

Две ловушки. Закон Гудхарта: метрика «покрытие документацией» немедленно порождает страницы-призраки ради галочки в чек-листе готовности сервиса — измерять надо не наличие, а свежесть, проверяемость и востребованность. И дашборд вместо действия: метрика полезна только тогда, когда её ухудшение кому-то создаёт задачу; отчёт, который никто не открывает, — тот же непрочитанный документ, просто в виде графика.

Ритуальное сопровождение: когда поддержка имитируется

Честная часть. Существует целый жанр работы, которая выглядит как поддержка документации, но ею не является: ежегодная аттестация документов, обязательная в регулируемых индустриях; пункт «документация обновлена» в definition of done; KPI «100% сервисов имеют описание». Распознаётся не по ощущению, а по следам:

  • Апрувы без диффа. В журнале страницы стоит «reviewed 2026-04-01», а последнее изменение содержимого — двухлетней давности. Ревизия была, чтения не было.
  • Массовая дата. Двести документов «проверены» в один вторник одним человеком. Арифметика не сходится ни при каком темпе чтения.
  • Бот, двигающий last_verified. Автоматизировали не проверку, а отметку о проверке, — и теперь свежесть невозможно отличить от её имитации.
  • «Документация обновлена» в чек-листе задачи, где документации не было и нет: галочка ставится, потому что без неё не закрывается тикет.
  • Страницы-призраки: README в каждом репозитории, потому что каталог сервисов красит репозитории без описания красным. Внутри — название сервиса и заголовок «TODO».

Что делать — по убыванию полезности. Разделить слои: аттестация для аудита ведётся отдельным реестром и не подмешивается в живую документацию, иначе доверие к рабочим текстам падает до уровня ритуальных. Требовать доказательство, а не отметку: ревизия закрывается либо диффом, либо записью «проверено, изменений нет, проверялось так-то» — она честнее галочки, потому что называет метод. Заменять подпись прогоном: last_verified проставляет зелёный прогон быстрого старта, а не человек. Считать честное время: «двести страниц по десять минут — 33 человеко-часа в квартал на подтверждение того, что никто не читал» — единственный язык, на котором такой разговор двигается вверх (см. «Работу вверх»).

Зеркальный вопрос перед тем, как обвинять процесс: когда вы последний раз открывали документ, который сами же обязали команду поддерживать? Если «никогда» — ритуал завели вы.

Типичные ошибки

  • Начинать с переписывания, а не с удаления. Поверхность поддержки растёт, результат тот же через квартал.
  • Один TTL на всё. У раннбука и ADR разная природа; общий срок ревью бессмысленен для обоих.
  • Владелец-человек. Уходит в отпуск, меняет команду, увольняется; владелец — группа или сервис в каталоге.
  • Копирование вместо включения. Каждая копия числа из конфига — запланированное расхождение с известной датой.
  • Смешение скоростей в одном абзаце. Абзац живёт по самому быстрому факту в нём.
  • Архив без вычистки из поиска и индекса ассистента. «В архиве» продолжает находиться и отвечать; удаление без надгробия ломает ссылки в тикетах, которые живут годами.
  • Метрика наличия вместо свежести и автоматизация отметки о проверке вместо самой проверки: и то и другое создаёт ложную уверенность быстрее, чем решает проблему.

Практика

  1. Разметьте каждый абзац своего самого читаемого документа классом изменчивости из таблицы. Всё, что быстрее «месяцев», вынесите в генерацию, включение или тикет.
  2. Найдите в нём мины («в настоящий момент», «планируется», «команда платформы») и замените. Замерьте, насколько текст стал короче.
  3. Поднимите один документ ровно на одну ступень: прогон быстрого старта в CI или таблица параметров из генерации. Оцените в часах — и потратьте их.
  4. Запустите скрипт разрыва по своему репозиторию, возьмите три худшие строки и заведите задачи с именами владельцев.
  5. Удалите пять страниц с нулевым трафиком, оставив надгробия. Через месяц посчитайте, сколько человек это заметили; результат обычно решает спор о том, нужна ли инвентаризация.

Мини-итог

  • Устаревание — экстерналия: платит меняющий код, выигрывает другой и позже. Расхождение не производит сигнала — в этом корень.
  • Ложь, дыра и дубль лечатся разным; охотиться начинают на ложь, а не на полноту.
  • Срок жизни абзаца равен сроку жизни самого быстрого факта в нём: разделяйте текст по скорости изменения, а не по темам.
  • Лестница проверяемости даёт единицу работы: «поднять документ на ступень» — задача с оценкой, «навести порядок в документации» — нет.
  • Один факт — один дом; копия стареет независимо. Владелец — группа или сервис в каталоге: реорганизация убивает документы чаще, чем невнимательность.
  • Срок жизни зависит от жанра, истечение видно читателю, нормальный исход просрочки — архив. Удаление — первоклассная операция; устаревший документ хуже отсутствующего.
  • Что не поддерживать — сознательный выбор; честная пометка «не поддерживается» полезнее вида актуальности.
  • Ритуальное сопровождение распознаётся по апрувам без диффа и массовым датам; лечится разделением слоёв, доказательством вместо отметки и подсчётом честного времени.

Источники

Что дальше

Все механизмы этой главы — генерация, TTL, владельцы, линтеры — сторожат факты. Ни один из них не заметит, что документ логически бессвязен, что вывод спрятан в конце, что термин употреблён в двух смыслах и что читатель после прочтения не сможет принять решение. Это умеет только человек, читающий чужой текст внимательно и по процедуре. Ревью текста — навык, который отличается от ревью кода сильнее, чем кажется: правки задевают авторство, а «мне не нравится» не является замечанием.

Ревью текста: как читать чужой документ и как принимать правки

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов