
Полная версия
Не верь. Не бойся. Не проси
FILEREADME.md
# Vibecode On-Prem Platform
Учебный путь от пустого Proxmox к управляемой on-prem платформе.
## Start here
1. Прочитай `ai_initial.md`.
2. Открой `plans/current-task.md`.
3. Проверь факты в `docs/architecture.md`.
4. Посмотри решения и открытые вопросы в `docs/decisions.md`.
## Current status
Stage zero. Инфраструктура и сетевой план ещё не определены.
README не обязан содержать историю цивилизации, полный inventory и инструкцию по восстановлению etcd, потому что если точку входа приходится читать пятнадцать минут - это уже не карта, а экскурсия. Следующий файл, ai_initial.md, назван намеренно нейтрально, поскольку разные агенты распознают собственные служебные файлы; если ваш инструмент требует AGENTS.md, CLAUDE.md или другой файл - перенесите туда тот же смысл.
FILE ai_initial.md
# AI operating contract
## Before work
1. Прочитай `README.md`, `ai_initial.md` и `plans/current-task.md`.
2. Прочитай только релевантные документы и исходники.
3. Сверь Goal, Scope, Out of Scope и Open Questions.
4. До редактирования покажи план.
## Permissions
- Read-only checks внутри scope разрешены.
- Локальные изменения разрешены только после согласования плана.
- Внешние и mutating actions требуют явного подтверждения.
- Destructive actions требуют отдельного предупреждения, плана восстановления и подтверждения.
## Never
- не выдумывай отсутствующие факты;
- не показывай и не записывай секреты;
- не расширяй scope словом «заодно»;
- не объявляй задачу готовой без verification.
## Session close
Покажи diff и результаты проверок. Обнови только изменившиеся документыпамяти.
Зафиксируй незавершённое и назови следующий безопасный шаг.
«Обнови память» не означает «перепиши все документы свежими словами»: если архитектура не изменилась, docs/architecture.md трогать не нужно, иначе факты начнут мутировать при каждом handoff, как рыба в рассказе человека, вернувшегося с рыбалки. Сам же architecture.mdсодержит подтверждённые факты, тогда как гипотезы и варианты живут в decisions.md.
FILE decisions.md
# Architecture
## Current state
- Stage: zero.
- Managed infrastructure: none.
- Confirmed nodes: none.
## Target direction
Proxmox → bastion → Terraform-managed VM → Ansible/AWX → Kubernetes → platform services → GitOps.
## Unknowns
- network and VLAN plan;
- DNS zones;
- Ubuntu and Proxmox versions;
- storage model;
- failure domains.
Разделение Current state и Target direction обязательно, поскольку «мы хотим три control plane» не означает «у нас есть три control plane», а в инфраструктуре будущее время особенно любит маскироваться под настоящее. Следующий файл, decisions.md, хранит решения и их цену: не только итог, но и причину выбора, альтернативы и последствия, - а пока решения нет, туда записывается открытый вопрос.
FILE decisions.md
# Decisions
## ADR template
- Date:
- Status: proposed | accepted | superseded
- Context:
- Alternatives:
- Decision:
- Consequences:
- Verification:
Последствия нужны потому, что архитектурное решение без цены подозрительно похоже на рекламу. Что до incidents.md, это память о том, что уже болело, и пока инцидентов нет - единственный момент проекта, когда данный файл выглядит оптимистично.
FILE incidents.md
# Incidents
## Template
- Symptom:
- Hypotheses:
- Checks:
- Root cause:
- Fix:
- Guardrail:
Формат здесь важнее полноты: не «Kubernetes сломался», а что увидел оператор, какой командой проверил гипотезу и что изменилось после исправления. Следом идёт runbooks.md- действия под давлением, и регламент это не лекция, а последовательность команд с условиями запуска, ожидаемым выводом и точкой остановки.
FILE runbooks.md
# Runbooks
## Repository bootstrap check
1. Выполнить `git status --short`.
2. Убедиться, что изменены только файлы текущего scope.
3. Просмотреть `git diff --check` и `git diff`.
4. Запустить настроенный secret scanner, если он есть.
5. Не коммитить, пока Open Questions выданы за факты.
Человек открывает регламент не для духовного роста: обычно у него уже красный мониторинг, два сообщения от руководителя и коллега, который спрашивает: «Ну что там?» Последний файл, current-task.md, работает как оперативная память, и в нём всегда должен быть ответ на вопрос «что мы делаем сейчас и что мешает закончить?»; меняется он чаще остальных именно потому, что играет роль оперативной памяти, а не семейного архива.
FILE current-task.md
# Current task: bootstrap project memory
## Goal
Создать проектную память и контракт работы с AI.
## Scope
- семь согласованных Markdown-файлов;
- протокол начала и закрытия сессии.
## Out of scope
- IaC и Kubernetes-код;
- установка инструментов;
- внешняя инфраструктура и секреты.
## Done
- [x] Согласованы роли документов.
## To do
- [ ] Проверить diff.
- [ ] Проверить, что неизвестные не выданы за факты.
## Open questions
- сеть, DNS, версии, storage и topology.
Представим вполне реалистичное продолжение, в котором агент создал семь файлов, а затем сообщает: «Для удобства я также добавил setup.sh, базовый .github/workflows/validate.yml и шаблон Terraform provider. Это ускорит следующий этап». Звучит разумно - и именно поэтому опасно, ведь дополнительные файлы не входили в область задачи, их требования не обсуждались, а workflow к тому же способен выполнять действия при будущем push. Выяснять, хороший ли там код, нам не нужно. Нарушен сам контракт.
ИНЖЕНЕР
Инженер: Стоп. Дополнительные файлы не были разрешены. Покажи их diff отдельно, удали только созданные тобой вне области задачи файлы и не меняй семь согласованных документов. Затем добавь в ai_initial.md guardrail: новые артефакты вне списка требуют отдельного согласования.
Получилась первая учебная цепочка. Антипаттерн: агент расширяет задачу «полезной» инициативой. Инцидент: в репозитории появляются нерассмотренные исполняемые файлы. Исправление: лишние артефакты удалены после проверки их происхождения. Предохранитель: список разрешённых файлов считается закрытым, расширение требует подтверждения. Важно не превращать это в истерику «AI снова всё испортил», поскольку агент сделал то же, что иногда делает увлечённый инженер, решивший немного улучшить соседнюю систему. Предохранитель нужен не потому, что одна сторона глупая, а потому, что обе стороны деятельные.
Остановившись, проверяем рабочее дерево:
TERMINAL
git status --short
git diff --check
git diff -- README.md ai_initial.md docs plans
Ожидаем ровно семь новых файлов, отсутствие ошибок пробелов и понятный diff. Затем ищем очевидные маркеры секретов и случайно придуманные адреса:
TERMINAL
rg -n -i 'password|token|secret|private.?key|BEGIN .* KEY' README.md ai_initial.md docs plans
rg -n '10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.' README.md ai_initial.md docs plans
Это sanity check - быстрая проверка здравого смысла, в силу того что регулярное выражение не знает всех форматов токенов, DNS-имён и внутренних идентификаторов. В реальном проекте понадобятся secret scanner, правила исключения чувствительных каталогов из контекста и внимательный просмотр diff. Наконец, проверяем, усвоил ли агент собственный контракт:
ИНЖЕНЕР
Прочитай ai_initial.md. Назови действия, которые разрешены без подтверждения, действия, требующие подтверждения, и три причины, по которым ты обязан остановиться.
Если ответ расплывчатый - проблема не обязательно в модели: возможно, правила написаны как корпоративные ценности на стене, то есть звучат благородно, но понять, что делать руками, по ним невозможно. Впрочем, самая честная проверка наших документов происходит не сейчас, а после закрытия чата, потому что новая сессия не знает устных договорённостей, интонации и того, что вчера под словом «кластер» вы имели в виду учебный стенд. Дайте новому агенту короткую команду:
ИНЖЕНЕР
Восстанови контекст проекта. Сначала прочитай README.md, ai_initial.md и current-task.md, затем только те документы, на которые они ссылаются для текущей задачи. Ничего не меняй. Верни Goal, Scope, Out of Scope, подтверждённые факты, неизвестные и следующий безопасный шаг.
Хороший ответ помещается в несколько абзацев и ссылается на файлы, тогда как плохой начинает заново интервьюировать вас о назначении проекта или уверенно сообщает параметры, которых в документах нет; в первом случае память работает, во втором - найдите, какой факт потерян или в каких двух документах он записан по-разному. Проектная память, кстати, тоже требует уборки: завершённая задача не должна вечно лежать в current-task.md, её результат переносится в архитектуру, решение, инцидент или историю Git, устаревшее решение получает статус superseded, а не исчезает, а регламент удаляется или исправляется, если команды больше не соответствуют системе. Иначе через полгода агент будет экономно читать четыре файла и экономно приходить к неверному выводу.
После проверки не закрываем ноутбук со словами «вроде нормально»: завтрашний агент не помнит сегодняшний разговор, а завтрашний вы, строго говоря, тоже помните его несколько оптимистичнее, чем было на самом деле.
Команда на завершение:
ИНЖЕНЕР
Закрой сессию и подготовь handoff. Проверь diff всех изменённых файлов и перечисли выполненные проверки. Обнови current-task.md, а остальные документы - только если содержащиеся в них факты действительно изменились. Зафиксируй открытые вопросы. Ничего не коммить и не переходи к следующей задаче. Назови один следующий безопасный шаг.
Хороший ответ содержит не настроение, а свидетельства:
FILEcurrent-task.md
## Handoff
- Созданы семь файлов проектной памяти.
- Удалены три неразрешённых артефакта вне scope.
- В ai_initial.md добавлен guardrail на создание новых файлов.
- Выполнены git status --short, git diff --check и ручной просмотр diff.
- Внешняя инфраструктура не изменялась.
- Открыты вопросы сети, DNS, версий, storage и topology.
- Следующий шаг: описать ownership и desired state до выбора инструментов автоматизации.
Слово «готово» без списка проверок ничего не стоит. Это просто хорошее настроение агента.
За одну сессию мы не построили ни одной виртуальной машины, зато получили рабочее место, память проекта, границы разрешений, протокол вопросов, проверку diff, первый инцидент и предохранитель. Теперь новый агент способен за несколько минут понять, где находится проект, что считается фактом и к чему ему нельзя прикасаться. Проверьте результат руками: закройте текущий чат, начните новую сессию и попросите агента прочитать точку входа, назвать текущую цель, неизвестные и запрещённые действия. Если для восстановления контекста требуется пересказать всю вчерашнюю беседу, память проекта не работает; если достаточно нескольких файлов, первый слой платформы уже построен. Он не отвечает ни на одном сетевом порту. Это пока его лучшее свойство.
И раз уж рабочее место готово, назовём три правила, вокруг которых собрана вся остальная книга. Они вынесены в её название, и у каждого два чтения: про инфраструктуру и про того, кто вам в ней помогает.
Не верь.В инфраструктуре - временным решениям: они переживают своих авторов, свои тикеты и иногда своих создателей. В работе с агентом - его интонации. Он одинаково уверенно пишет проверенное и выдуманное, потому что уверенность в его тексте не измерение, а выученная манера. Скидку делайте в обе стороны - и на «безусловно», и на «пожалуй». Единственный неподдельный сигнал: может ли он предъявить проверку, которая упадёт, если он неправ.
Не бойся.В инфраструктуре - делать руками и лезть внутрь, вместо того чтобы верить зелёному индикатору. В работе с агентом - того, что проверка выглядит как недоверие. Она не отношения выясняет, она и есть форма работы. Вопрос «с чем ты сверялся?» продуктивен. Вопрос «ты уверен?» - нет: у агента нет доступа к собственной уверенности, и он ответит «да» ровно так же убедительно, как отвечал всё остальное.
Не проси.В инфраструктуре - сделать за тебя то, за что отвечаешь ты. В работе с агентом - определить, что значит «готово». Вот это нельзя отдавать никогда: критерий готовности агент задаст как «то, что я произвёл», и не из хитрости - у него просто нет другого источника. Сюда же относится вторая подмена, менее заметная: он с той же готовностью определит за вас и то, о чём именно его попросили.
Дальше эти три правила не повторяются мантрой - они проверяются, и в каждой главе найдётся место, где одно из них можно нарушить и посмотреть, что из этого выйдет.
В следующей главе мы разберём desired state и владельцев изменений. До появления Terraform, Ansible и Kubernetes нужно решить, кто отвечает за VM, операционную систему, кластерные объекты и приложения. Иначе три замечательных инструмента начнут исправлять друг друга, а инженер получит редкую возможность наблюдать вечный двигатель в пределах собственного дата-центра.
Глава 2. Не просите AI чинить: научите его расследовать
Инженер показывает AI одну строку ошибки и пишет: «Почини».
AI отвечает мгновенно и предлагает очистить кэш, перезапустить сервис, переустановить пакет, отключить файрвол и добавить запись в /etc/hosts, причём какое-нибудь из этих действий иногда даже помогает. После этого система снова работает, причина остаётся неизвестной, а в инфраструктуре появляется ещё одно временное решение с прекрасными шансами пережить автора.
Так рождаются технические легенды. «Этот сервис по вторникам надо рестартовать два раза». «DNS здесь особенный». «Строку не трогай, без неё всё падает». Никто уже не помнит, откуда взялась строка, зато она заботливо переносится из одного поколения конфигурации в другое, как фамильное проклятие, и через три года, когда вы будете мигрировать на новый кластер, кто-нибудь обязательно спросит: «А мы перенесли эту магическую строку?» - и ответить не сможет никто. Но перенесут. На всякий случай.
AI особенно опасен в таком режиме вовсе не оттого, что плохо ищет ошибки; беда ровно в обратном - он очень быстро находит правдоподобные объяснения, и когда контекста мало, правдоподобие начинает подменять доказательство. Модель узнаёт знакомый симптом и достраивает остальную историю по наиболее вероятному шаблону, иногда угадывая. Вот здесь и важно понять, что в production слово «иногда» перестаёт быть статистической погрешностью и становится бомбой с часовым механизмом, которая просто ждёт своего часа.
Задача этой главы - не устанавливать софт: мы снова ничего не будем ставить. Да, опять. Да, так надо. Научиться нужно другому - расследовать сбой вместе с AI: собрать свидетельства, отделить факт от гипотезы, проверить версии по одной, найти не только непосредственную причину, но и системную, а затем сохранить знание в проекте. Это ещё не Linux-диагностика, ею займёмся позже; сейчас мы строим сам процесс мышления, которым потом будем разбирать Linux, сеть, Terraform, Kubernetes и всё остальное, что умеет ломаться с гораздо большим размахом. А начинать придётся с терминов, потому что слово «ошибка» обычно используют сразу для пяти разных вещей.
Симптом- то, что заметил человек или мониторинг: страница не открывается, команда завершилась неуспешно, файл не появился. Симптом сообщает, где болит, но редко объясняет почему.
Свидетельство- наблюдаемый факт: точная команда, время, код возврата, строка лога, diff, состояние процесса. Свидетельство можно повторно проверить или привязать к источнику.
Гипотеза- возможное объяснение свидетельств: «имя не резолвится из-за отсутствующей DNS-записи» - гипотеза, которая становится полезной только вместе с проверкой, способной её опровергнуть.
Непосредственная причина- конкретное условие, из-за которого операция не выполнилась именно сейчас: например, в конфигурации остался «enter_your_ip_here».
Системная причина- объяснение того, почему неправильное условие прошло через процесс незамеченным: скрипт не проверил заглушку, проигнорировал ошибку curl, напечатал сообщение об успехе и вернул код 0. Исправить только имя узла - значит убрать непосредственную причину и сохранить фабрику следующих инцидентов.
Исправление(fix) восстанавливает правильное поведение, тогда как предохранитель(guardrail) меняет код или процесс так, чтобы тот же класс ошибки не проходил бесшумно. Перезапустить сервис можно считать исправлением; добавить проверку конфигурации до запуска и функциональный health check после - предохранитель.
AI должен работать именно с этой цепочкой, и если агент перескакивает от симптома прямо к исправлению, он не расследует. Он участвует в лотерее с очень убедительными комментариями.
В будущем нам понадобится stage-zero bootstrap - минимальный ручной этап, который подготовит вход в инфраструктуру до появления полноценной автоматизации; поскольку никакой инфраструктуры пока нет, проверим только локальную механику будущей предстартовой проверки. Представим, что агент предложил такой черновик:
TERMINAL
#!/usr/bin/env bash
MANAGEMENT_HOST="${MANAGEMENT_HOST:-control.example.invalid}"
echo "Checking management endpoint..."
curl -s "https://${MANAGEMENT_HOST}/health" || true
echo "Stage-zero preflight completed successfully"
Домен .invalid зарезервирован именно для примеров и не должен разрешаться в реальный адрес. Запускаем скрипт:
TERMINAL
$ ./stage-zero-preflight.sh
Checking management endpoint...
Stage-zero preflight completed successfully
$ echo $?
0
На экране нет даже ошибки: curl работает в тихом режиме, а || true превращает любой его результат в успех. Скрипт не проверил точку подключения, но сообщил, что проверил, и это хуже честного падения, поскольку красный статус хотя бы мешает идти дальше, тогда как ложный зелёный открывает ворота следующему шагу. || true в продакшене - это как заклеить лампочку Check Engine на приборной панели изолентой. Машина едет, индикатор не горит, все счастливы. До первого перегрева.
Не исправляйте код сразу: сейчас важнее правильно поставить задачу агенту. Новая сессия начинается с восстановления памяти проекта, после чего агенту назначается роль исследователя - read-only, без редактирования и выполнения команд. Мы не написали «ты Senior SRE с тридцатилетним опытом и IQ размером с дата-центр», поскольку ролевая биография не заменяет протокол, а по факту является продуктом маркетинга и попыткой сыграть на «комплексе менеджера». Настоящий Senior SRE не говорит «я всё знаю» - он говорит «я не знаю, но знаю, как это проверить». Именно этому мы учим агента.
Конец ознакомительного фрагмента.
Текст предоставлен ООО «Литрес».
Прочитайте эту книгу целиком, купив полную легальную версию на Литрес.
Безопасно оплатить книгу можно банковской картой Visa, MasterCard, Maestro, со счета мобильного телефона, с платежного терминала, в салоне МТС или Связной, через PayPal, WebMoney, Яндекс.Деньги, QIWI Кошелек, бонусными картами или другим удобным Вам способом.

