JavaRush /Курсы /Claude code /Песочница для рискованных операций

Песочница для рискованных операций

Claude code
23 уровень , 3 лекция
Открыта

1. Песочница нужна даже при настроенных permissions

Когда люди впервые слышат про sandboxing, легко подумать: «Но мы же уже настроили permissions, deny-правила и protected paths, зачем ещё слой?» На самом деле это другой слой. Permissions отвечают на вопрос, что можно делать. Песочница — где это можно делать без катастрофы.

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

Нагляднее всего разницу видно в маленькой таблице:

Вопрос Permissions Песочница
На что отвечают Какие действия разрешены Где выполняются действия
Что уменьшают Вероятность опасного шага Цену ошибки
Типичный пример deny для .env* и payments/** test DB вместо production DB
Чего не заменяют Git, тесты, review permissions, review, здравый смысл

Представьте, что вы учите человека водить машину. Permissions — это правило «нельзя ехать на красный». Песочница — автодром, а не оживлённое Садовое кольцо. Нужны оба разом. Дать Claude экспериментировать прямо на production — это квест в жанре «угадай, кто сегодня не спит».

Главное правило этой лекции простое: Claude должен экспериментировать там, где откат возможен быстро, дёшево и без настоящих данных.

Поэтому грамотный workflow не только запрещает лишнее, но и заранее выбирает среду, где даже разрешённое действие не нанесёт дорогой ущерб.

2. Ветка и worktree — два доступных уровня изоляции

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

Ветка — это минимальный уровень изоляции. Она хорошо годится для review-required задач: меняете код, гоняете тесты, читаете diff и не трогаете среду вокруг проекта. Поправить сортировку refund-запросов в support inbox, подчистить код в support/ без правок инфраструктуры — ветки хватает: не мешаете main, коммитите мелко, откатываетесь в любой момент.

Worktree — это уже следующая ступень: вторая директория с тем же репозиторием, но в отдельной ветке. Если ветка — новая линия истории, то worktree — ещё и вторая рабочая комната: в одной обычная работа, в другой — эксперимент, который не пачкает текущую папку, не конфликтует с открытыми в IDE файлами и не гоняет вас туда-сюда.

git switch main
git pull
git worktree add ../commerce-os-boot-upgrade -b chore/boot-upgrade
cd ../commerce-os-boot-upgrade
claude  # Claude работает в отдельной директории и не трогает основную копию

Такой подход особенно хорош, когда задача уже пахнет «осторожно, это может поломать сборку»: обновить библиотеку отчётов, перестроить Gradle-конфиг, проверить альтернативную реализацию. Главное удобство worktree даже не в Git как таковом — в психологическом комфорте: вы видите, что эксперимент живёт отдельно, и соблазн сделать опасное «быстренько здесь же» резко падает.

Но у worktree есть честное ограничение: он изолирует файлы и Git-состояние — и не изолирует ОС, переменные окружения, занятые порты, локальную базу. Меняете код — отлично. Меняете ещё и среду — worktree уже мал.

3. Одной ветки мало — контейнер и VM

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

Контейнер разработки — это удобный способ отделить зависимости и окружение от основной машины. Он особенно полезен при обновлении рантайма, сборочного инструмента, системных библиотек, локальных сервисов, сложного набора зависимостей. Хороший пример — risky dependency upgrade в Commerce OS, задевающий backend, PostgreSQL и тестовый профиль приложения: после такого эксперимента основная локальная версия проекта должна запускаться как ни в чём не бывало.

services:
  db-test:
    image: postgres:18.3
    environment:
      POSTGRES_DB: commerce_test
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
    tmpfs: /var/lib/postgresql/data  # данные исчезнут после остановки

Контейнер здесь даёт особенно важную вещь — эфемерность. Остановили — среда исчезла. Никаких долгоживущих «ой, у меня в локальной базе осталось что-то странное ещё с прошлого четверга». Для risky operations эффект почти терапевтический.

Виртуальная машина нужна реже, но она полезна там, где контейнера уже мало: проверить команды у системного уровня, включить агрессивный permission mode на одноразовый эксперимент, повозиться с непроверенными утилитами. Контейнер изолирует среду неплохо, VM даёт границу жёстче: отдельную ОС, отдельную ФС, отдельную сетевую картину мира. Тяжелее и медленнее — да. Ради правки README — смешно. Ради рискованного сценария — правильная цена за спокойствие.

И здесь важно не впасть в другую крайность. Dev container и VM не нужны ради каждого опечатанного метода: песочница должна быть соразмерна риску — иначе разработка превращается в бюрократический спорт.

4. Данные тоже должны жить в песочнице

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

Если рискованная операция касается базы, очередей, платежей, массовых обновлений, импортов или скриптов очистки — нужна не просто отдельная папка с кодом, а отдельные данные, синтетические или тщательно санитизированные. Production dump с одной замазанной колонкой — всё ещё слишком близко к настоящим клиентам, заказам и проблемам.

{
  "orderId": "test-order-1001",
  "customerEmail": "demo@example.com",
  "refundAmount": 49.99,
  "currency": "USD",
  "reason": "duplicate-order"
}

Такой пример выглядит скучно, но в этом и его прелесть: он похож на реальность настолько, чтобы воспроизвести сценарий, и при этом без реальных customer данных. Именно это и есть здравая инженерия, а не «давайте просто возьмём дамп продакшена, мы же аккуратно».

То же самое касается конфигурации. Если хватает .env.example — не тащите настоящий .env. Если заводится application-test.yml — не запускайте эксперимент на боевом профиле. Если нужен доступ к БД — пусть это будет test DB с фейковыми учётными данными, а не production-credential, который «я потом удалю». История разработки знает много страшных слов, и одно из самых страшных — «потом».

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

5. Выбор песочницы по уровню риска

Когда терминов становится много, очень хочется волшебную кнопку «подскажи, что брать». И такая кнопка в реальной команде обычно оборачивается маленькой матрицей выбора. Держите её прямо в Workflow Kit, рядом с RISK_CLASSIFICATION.md, — чтобы решение принималось по привычке, а не по вдохновению.

Ниже — компактная версия такой матрицы для Commerce OS:

Ситуация Минимально разумная песочница Почему
README, docs, маленький локальный refactor отдельная ветка Изолируем diff, больше ничего не нужно
Многофайловая правка в support/ ветка или worktree Нужна чистая история и безопасный откат
Dependency upgrade, build-эксперимент worktree + контейнер Изолируем и файлы, и окружение
Schema/data change worktree + test DB + synthetic data Нельзя трогать реальные данные
Write-capable MCP контейнер или VM + test env Ошибка не должна выйти в production
Массовый delete/refactor script throwaway repo/worktree + sample data Нужно сначала «проиграть» сценарий

А вот как выбор фиксируется в артефакте:

## Обновление зависимостей
Риск: review-required
Песочница: worktree + dev container
Данные: только test DB
Разрешено: edit, build, tests
Запрещено: production secrets и push в main

Заметьте, как красиво здесь сходятся предыдущие лекции и сегодняшняя. Риск уже классифицирован. Capability envelope уже понятен. Теперь к нему просто добавляется конкретная среда исполнения — и решение выходит взрослым: не «посмотрим по ходу», а «вот где именно разрешено экспериментировать».

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

6. Commerce OS: массовые операции без героизма

Лучше всего идея песочницы закрепляется на конкретном сценарии. Представьте Commerce OS: массовое исправление статусов refund-запросов после сбоя в старом процессе импорта. Безобидной задача не выглядит — касается данных, может задеть финансы, испортить историю заказов. «Просто открою Claude в основной папке и посмотрим» — плохой план.

Сначала команда классифицирует задачу как review-required с близостью к high-risk. Уже на этом шаге становится ясно: никаких real credentials, никаких действий против production DB, никакого permissive mode в основной копии. Дальше — отдельный worktree, а рядом test DB в контейнере, в неё грузится синтетический набор refund-сценариев: частичный возврат, дубликат, отмена, ручная проверка.

Дальше workflow примерно такой:

flowchart TD
A[Классифицировали риск] --> B[Создали worktree]
B --> C[Подняли test DB]
C --> D[Claude работает только в песочнице]
D --> E[Проверили diff и тесты]
E --> F[Человек принимает решение]

В этот момент Claude уже очень полезен: найдёт затронутые классы, предложит безопасный SQL или Java-сценарий, поможет с regression-тестами, проверит, не выходит ли diff за рамки refunds/ и support/. Но всё это внутри среды, где ошибка дешёвая. Скрипт пометил лишние записи — откатываете test DB. Сломал build — worktree удаляется, основная копия чиста. Возникло сомнение в логике — пересматриваете план, не трогая ничего настоящего.

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

7. Dry-run, backup и staging не заменяют песочницу

Здесь начинаются тонкие, но очень важные различия. Многие разработчики, услышав слово «sandbox», отвечают: «У нас есть dry-run» или «Мы делаем backup перед запуском». Механизмы полезные — но не тождественны песочнице: они про другое.

Механизм Что даёт Чего не даёт
Dry-run Показывает предполагаемое действие Не проверяет реальные побочные эффекты среды
Backup Даёт шанс откатиться после беды Не делает ошибку дешёвой и быстрой
Staging Даёт похожую среду Не всегда изолирована и часто общая для команды

Dry-run — это хорошая репетиция без выполнения. Но что произойдёт при настоящем изменении состояния, он не проверяет: скрипт красиво печатает план обновления, а на реальном запуске падает из-за локов, прав, неожиданной схемы или несоответствия версии библиотеки. Backup — это вообще не про профилактику, а про спасение после аварии: жить только за счёт backup — как ездить без тормозов, зато с хорошей страховкой.

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

Именно поэтому «мы же сделали backup» — не оправдание отсутствия песочницы. Backup — ремень безопасности после ошибки. Песочница — автодром до ошибки. Разница, как видите, весьма ощутимая.

8. Песочница не заменяет дисциплину

Есть соблазн увидеть в sandboxing волшебную таблетку: мол, есть worktree, test DB и контейнер — можно расслабиться, «Claude сам разберётся». К сожалению, инженерия так не работает. Песочница не заменяет маленькие diff, чтение изменений глазами, тесты — и уж точно не отменяет человеческое решение там, где ставка высока.

Ловушки те же, что уже разбирали: настоящий .env в worktree, почти production dump в test DB. Формально песочница есть, фактически нет. Ещё одна классика — включить permissive mode и решить, что раз всё в отдельной папке, можно не следить, какие команды Claude запускает. Но отдельная папка не изолирует shell-эффекты на вашей машине, не защищает системные каталоги и не гарантирует, что кто-то не смотрит в неправильную базу.

Есть и более будничные промахи. Например, worktree сделали — а через неделю не понимаете, откуда «ещё одна почти такая же ветка», удалить забыли. Или контейнер подняли на тестовом профиле, а приложение подключилось к старой локальной БД, потому что переменная окружения осталась прежней. Именно в такие моменты и видно: sandboxing — не роскошь и не красивый термин из политики команды. Это привычка проверять, чем вы на самом деле управляете: только папкой, папкой и средой, или папкой, средой и данными разом.

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

Но сделать ошибку дешёвой — ещё не то же, что разрешить change идти дальше. Sandbox страхует эксперимент, а право на путь в prod-sensitive зону оформляется отдельно: через deployment boundary и человеческое go/no-go решение.

1
Задача
Claude code, 23 уровень, 3 лекция
Недоступна
Создайте отдельный worktree через terminal
Создайте отдельный worktree через terminal
1
Задача
Claude code, 23 уровень, 3 лекция
Недоступна
Подготовка docker-compose.test.yml для test DB
Подготовка docker-compose.test.yml для test DB
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ