✻ Claude Code по-русски
🎧 Аудиокурс
🎧 Озвучка этой страницы готовится.

#Ограничьте автономные запуски

Продвинутый уровень · Урок 7 из 7 · около 20 минут плюс время запуска · Нужно: Скрипты с claude -p, Поделитесь настройкой с командой · Сверено с Claude Code v2.1.285 (stable) 09.10.2026

#Цель

К концу урока вы сможете ограничить запуск claude -p без присмотра минимальными привилегиями, песочницей, лимитами ходов и расходов, точкой ревью и оценкой стоимости.

#Что понадобится

#Идея

Запуск, за которым никто не следит, делает всё, что вы разрешили заранее, поэтому разрешайте мало, а остальное ограничивайте:

#Разбор примера

Работайте в своём репозитории. Папки src/ и test/ и команда npm test обозначают ваши собственные: везде ниже подставьте свои.

  1. Сохраните ограничения как .claude/bounded-run.json:
{
  "permissions": {
    "allow": ["Edit(./src/**)", "Edit(./test/**)", "Bash(npm test *)"],
    "deny": ["Agent", "Read(./.env)", "Read(./.env.*)", "Bash(git commit *)", "Bash(git push *)"]
  },
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,
    "autoAllowBashIfSandboxed": false
  }
}

Файловые инструменты Claude не могут изменить этот файл во время запуска: в режиме dontAsk запись в защищённую папку .claude/ запрещена, и правила allow этого не меняют (Protected paths). 2. Сохраните скрипт запуска как scripts/bounded-run.sh:

#!/bin/bash
# Runs one unattended task inside the bounds in .claude/bounded-run.json.
set -u
if [ $# -ne 2 ]; then
  echo 'Usage: scripts/bounded-run.sh "<task>" <result.json>' >&2
  exit 2
fi
before=$(git rev-parse --short HEAD)
claude -p "$1" \
  --setting-sources project \
  --settings .claude/bounded-run.json \
  --permission-mode dontAsk \
  --model sonnet \
  --max-turns 15 \
  --max-budget-usd 2 \
  --output-format json > "$2"
status=$?
jq '{subtype, num_turns, total_cost_usd, denied: [.permission_denials[]? | .tool_input.command // .tool_name]}' "$2"
echo "HEAD before: $before, after: $(git rev-parse --short HEAD)"
git status --short
exit "$status"
chmod +x scripts/bounded-run.sh
git add scripts/bounded-run.sh .claude/bounded-run.json
git commit -m "Add a bounded runner for unattended tasks"

Если git сообщает, что путь игнорируется, git check-ignore -v <path> покажет совпавшее правило; добавьте путь через git add -f. 4. Посмотрите, как лимит останавливает запуск. Задайте тем же ограничениям крошечный лимит расходов:

claude -p "Run npm test and summarize the result" \
  --setting-sources project --settings .claude/bounded-run.json \
  --permission-mode dontAsk --model sonnet \
  --max-budget-usd 0.01 --output-format json > .practice/a-7-capped.json
echo "exit $?"
jq '{subtype, total_cost_usd}' .practice/a-7-capped.json

Будет выведен ненулевой код выхода, затем "subtype": "error_max_budget_usd": запуск остановился на лимите, и JSON всё равно его фиксирует (Handle the result). total_cost_usd может превышать лимит, потому что включает ответ, который его пересёк (Track costs on failed conversations). 5. Оцените стоимость на срезе — одной небольшой части большей задачи:

scripts/bounded-run.sh "Use your Edit tool to add a test for one untested function in src/<file>. Then run npm test as a command on its own, and then commit the test." .practice/a-7-slice.json

Сводка покажет "subtype": "success", число использованных ходов, total_cost_usd, а в denied — каждый вызов, отклонённый вашими ограничениями, например git commit; ваш список будет другим. HEAD до и после одинаковый, а git status показывает новый тест, не закоммиченный. Вывод у вас будет другим. total_cost_usd — оценка на стороне клиента, а не ваш счёт (Track cost and usage); на плане Claude /usage в сессии показывает лимиты использования плана (Commands). Чтобы ограничить всю задачу, умножьте стоимость среза пропорционально и задайте лимит расходов выше, с запасом. 6. Будьте точкой ревью. Прочитайте каждое изменение через git status и git diff, включая файл ограничений, сами запустите npm test и закоммитьте только то, что принимаете. Для второго мнения запустите claude и поручите субагенту проверить diff в свежем контексте и сообщить о пробелах (Add an adversarial review step).

#Ваша очередь

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

Критерии приёмки:

#Проверка

Урок пройден, когда выполнено всё это:

Запустите npm run check -- a-7 --dir <your repo> из своей копии для практики или npm run check -- a-7 в самой копии. Проверка запускает ваш закоммиченный скрипт с заглушкой вместо claude, так что ваш лимит не расходуется.

Если не проходит первый пункт, убедитесь, что закоммиченный скрипт исполняемый (git ls-files -s scripts/bounded-run.sh начинается с 100755), вызывает claude по имени, а не по пути и не через npx, и не задаёт PATH: проверка читает закоммиченный скрипт, так что коммитьте каждое исправление. Если не проходит правило allow, сузьте его до одной папки или команды, нужной задаче. Если пункт о песочнице называет ключ, добавьте его в файл настроек: без failIfUnavailable запуск, чья песочница не может стартовать, выполняется без песочницы (sandbox.enabled). Если не проходит пункт о срезе, убедитесь, что скрипт отправляет по пути результата только JSON-вывод claude (stdout), и снова выполните шаг 5; срез, завершившийся error_max_budget_usd, означает, что ваш лимит расходов меньше стоимости одного среза, — поднимите его.

#Осторожно

#Что дальше


Источники: Choose a permission mode · Configure permissions · Extend Claude with skills · Configure the sandboxed Bash tool · All settings · Settings files and precedence · CLI reference · Create custom subagents · Run Claude Code programmatically · How the agent loop works · Track cost and usage · Manage costs effectively · Commands · Best practices · Orchestrate subagents at scale with dynamic workflows

← Поделитесь настройкой с командой · Оглавление Продвинутого уровня · Итоговый проект Продвинутого уровня → · Тема: Разрешения и безопасность · Застряли на уроке?