Модуль 2 · Направляющие · урок 8 из 24
Документация как система записи
AGENTS.md — оглавление. Этот урок о том, на что оглавление ссылается. Команда OpenAI называет базу знаний в репозитории системой записи (system of record): единственным авторитетным местом, где живут архитектура, решения, спецификации и планы. Разберём их структуру, адаптируем её к проектам агентства и сделаем так, чтобы документация не гнила.
Почему именно репозиторий
Главный аргумент из статьи «Harness engineering»: для агента знаний в Google Docs, чатах и головах людей нет. Он видит только версионируемые артефакты — код, markdown, схемы, исполняемые планы. Авторы приводят пример: если архитектурное решение согласовали в мессенджере, а агент не может его найти, оно бесполезно — так же, как для нового сотрудника, который придёт через три месяца.
У системы записи в репозитории есть свойства, которых нет у вики:
- Версия совпадает с кодом. Документ в ветке описывает код в этой же ветке.
- Изменения ревьюятся. Правка архитектурного решения проходит через MR, как код.
- Её можно проверять программой. Ссылки, структура, свежесть, полнота индекса.
- Агент может её чинить. Расхождение документа и кода превращается в обычную задачу.
Структура по образцу OpenAI
В статье описана такая организация знаний (схема наша, состав — из статьи):
AGENTS.md # ~100 строк, оглавление
ARCHITECTURE.md # домены, слои, границы
docs/
├── design-docs/
│ ├── index.md # каталог со статусом проверки каждого документа
│ └── core-beliefs.md # базовые принципы команды
├── exec-plans/
│ ├── active/
│ ├── completed/
│ └── tech-debt-tracker.md
├── generated/
│ └── db-schema.md # генерируется, руками не правится
├── product-specs/
├── references/ # *-llms.txt для внешних зависимостей
├── DESIGN.md FRONTEND.md PLANS.md PRODUCT_SENSE.md
└── QUALITY_SCORE.md RELIABILITY.md SECURITY.mdНесколько деталей из статьи, которые легко пропустить:
- дизайн-документы каталогизированы, у каждого есть статус проверки;
- документ качества ставит оценку каждому домену и архитектурному слою и отслеживает пробелы во времени;
- планы — полноценные артефакты с журналами прогресса и решений (им посвящён следующий урок);
- структура базы знаний проверяется линтерами и задачами CI: актуальность, перекрёстные ссылки, структура.
Адаптация к агентству
У агентства своя специфика: решения рождаются на созвонах с клиентом, в комментариях к задаче в Kaiten, в переписке. Требования приходят документом от аналитика, макеты — в Figma. Ничего из этого агент не увидит, пока не появится файл в репозитории.
Наш вариант для проекта на OctoberCMS:
docs/
├── ARCHITECTURE.md # плагины, компоненты, сервисы, кто от кого зависит
├── decisions/ # короткие записи решений: контекст, решение, последствия
│ └── index.md
├── product-specs/ # требования клиента в виде проверяемых сценариев
├── integrations/ # CRM, платёжка, почта: контракты, ошибки, тестовые стенды
├── references/ # octobercms-llms.txt, design-system-llms.txt
├── generated/ # схема БД, список маршрутов — только генерация
├── exec-plans/
├── CODESTYLE.md
└── DEPLOYMENT.mdРабочее правило: решение не принято, пока не записано в docs/decisions/. Обсудили на созвоне, что кэш каталога сбрасывается по событию из CRM, а не по таймеру, — через десять минут после созвона это коммит в decisions/ со ссылкой на задачу. Записывать может и сам агент: дайте ему заметки со встречи и попросите оформить решение по шаблону.
---
status: accepted
owner: backend-lead
verified: 2026-10-14
task: KAITEN-12345
---
# Сброс кэша каталога по событию CRM
## Контекст
Цены меняются в CRM несколько раз в день, таймер на 1 час давал устаревшие цены.
## Решение
Кэш каталога сбрасывается вебхуком `catalog.updated` из CRM. Таймер удалён.
## Последствия
- Если вебхук не дошёл, цена устареет до следующего события. Мониторинг — docs/RELIABILITY.md.
- Новые места кэширования каталога обязаны подписываться на это же событие.Сгенерированное — не редактируется
Часть знаний не нужно писать вообще: её можно вывести из кода. Схема базы, список маршрутов, перечень консольных команд. Такие документы лежат в docs/generated/, создаются одной командой, а CI проверяет, что они не отстали от кода.
docs-generated:
@mkdir -p docs/generated
@docker compose exec -T db sh -c 'mysqldump --no-data --skip-comments -uroot -p"$$MYSQL_ROOT_PASSWORD" "$$MYSQL_DATABASE"' | sed 's/ AUTO_INCREMENT=[0-9]*//' > docs/generated/db-schema.sql
docs-check: docs-generated
@git diff --exit-code docs/generated || (echo "docs/generated устарел: выполните make docs-generated и закоммитьте результат"; exit 1)Агенту это даёт точную схему без чтения десятков миграций, а людям — гарантию, что документ не врёт.
Механические проверки базы знаний
Документ без владельца и даты проверки рано или поздно начнёт врать, и никто этого не заметит. Простой скрипт закрывает основные дыры: обязательные поля, давность проверки, присутствие в индексе. Сообщения снова написаны как инструкции.
#!/usr/bin/env python3
"""Проверка базы решений: front matter, давность проверки, индекс."""
import datetime
import pathlib
import re
import sys
root = pathlib.Path(__file__).resolve().parents[1]
folder = root / "docs" / "decisions"
index_file = folder / "index.md"
index = index_file.read_text(encoding="utf-8") if index_file.exists() else ""
MAX_AGE_DAYS = 180
errors = []
for f in sorted(folder.glob("*.md")):
if f.name == "index.md":
continue
rel = f.relative_to(root)
text = f.read_text(encoding="utf-8")
m = re.match(r"^---\n(.*?)\n---\n", text, re.S)
meta = dict(re.findall(r"^(\w+):\s*(.+)$", m.group(1), re.M)) if m else {}
for key in ("status", "owner", "verified"):
if key not in meta:
errors.append(f"{rel}: нет поля {key} во front matter — добавьте его.")
try:
age = (datetime.date.today() - datetime.date.fromisoformat(meta.get("verified", "").strip())).days
if age > MAX_AGE_DAYS and meta.get("status", "").strip() != "superseded":
errors.append(f"{rel}: проверен {age} дн. назад — сверьте с кодом и обновите verified.")
except ValueError:
errors.append(f"{rel}: verified должен быть датой ГГГГ-ММ-ДД.")
if f.name not in index:
errors.append(f"{rel}: нет в docs/decisions/index.md — добавьте строку в индекс.")
print("\n".join(errors) or "docs: OK")
sys.exit(1 if errors else 0)Проверку давности разумно сначала запускать как предупреждение (allow_failure: true в GitLab CI), а блокирующей делать, когда база приведена в порядок.
Агент-садовник
Последний элемент из статьи OpenAI — периодический агент doc-gardening. Он ищет документы, которые расходятся с реальным поведением кода, и открывает PR с исправлениями. Это частный случай фоновой уборки, которой посвящён урок об энтропии. Технически — задача по расписанию или codex exec в CI, об этом урок о задачах по расписанию.
Начинать лучше с узкой задачи: «сверь docs/integrations/crm.md с кодом в plugins/.../classes/Crm и предложи правки». Широкое «проверь всю документацию» даёт шумный результат.
Попробуйте сами
10–15 мин на рабочем месте- Вспомните три решения по своему проекту, принятые за последний месяц вне репозитория. Попросите агента оформить их в
docs/decisions/по шаблону из урока, передав ему свои заметки. - Выберите одно знание, которое можно генерировать (схема БД, маршруты, список событий), и сделайте для него цель в Makefile с проверкой
git diff --exit-code. - Запустите узкую сверку документа с кодом:
Сравни docs/integrations/crm.md с фактическим кодом интеграции.
Выпиши расхождения таблицей: утверждение в документе — что в коде — файл.
Файлы не меняй.Коротко
- Система записи — репозиторий: всё остальное для агента не существует.
- Структура OpenAI: ARCHITECTURE.md, design-docs со статусами, exec-plans, generated, product-specs, references.
- Решение не принято, пока не записано в
docs/. - Выводимое из кода — генерируется и проверяется в CI, а не пишется руками.
- Владелец, дата проверки, индекс и агент-садовник не дают документации гнить.