Claude Code снёс прод за 9 секунд. 7 хуков на ночь

Claude Code снёс прод за 9 секунд. 7 хуков на ночь

В апреле 2026 основатель PocketOS оставил Cursor с Claude Opus в режиме --dangerously-skip-permissions на ночь, чтобы агент закончил рефакторинг. Утром не было ни прод-базы, ни бэкапов. На дамп через Railway API ушло 9 секунд.

; then\n jq -n '{\n \"hookSpecificOutput\": {\n \"hookEventName\": \"PreToolUse\",\n \"permissionDecision\": \"deny\",\n \"permissionDecisionReason\": \"rm -rf без явной директории. Укажи путь.\"\n }\n }'\nfi\nexit 0","lang":"bash"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003EХук 5 - Ask-for-new-deps.\u003C/b\u003E Установка нового пакета через npm install <name>, pip install <name>, uv add <name> уходит в permissionDecision: ask. Чистый npm install без аргумента (восстановление по lockfile) проходит без вопросов.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003EХук 6 - Audit-log.\u003C/b\u003E Каждая Bash/Write/Edit-команда пишется в .claude/audit.jsonl. После инцидента есть кому показать хронологию без догадок.\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"{\n \"matcher\": \"Bash|Write|Edit\",\n \"hooks\": [{\n \"type\": \"command\",\n \"command\": \"jq -c '{ts: now, tool: .tool_name, cmd: (.tool_input.command // .tool_input.file_path), cwd: .tool_input.cwd}' \u003E\u003E ${CLAUDE_PROJECT_DIR}/.claude/audit.jsonl; exit 0\"\n }]\n}","lang":"json"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003EХук 7 - Block-deploy-from-bypass.\u003C/b\u003E Если сессия запущена с --dangerously-skip-permissions, любая команда деплоя (vercel deploy, coolify, railway up --detach, flyctl deploy) отменяется. Чтобы выложить на прод, переключись в обычный режим - это секундное действие, но останавливает агента.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЭти семь хуков покрывают пять классов инцидентов: DDL-удаление, force-push, утечка секретов, файловый снос, supply-chain через свежий пакет. Шестой добавляет наблюдаемость. Седьмой страхует именно автономный режим, где --dangerously остаётся включённым дольше задачи.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EИз семи готовых bash-снипетов выше скопируй три блока кода (хуки 1, 2, 4) и audit-log (хук 6). Хуки 3, 5, 7 собираются по аналогии за минуту: возьми тот же jq -n-шаблон, поменяй регекс в grep.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"auto-mode даёт 17% ложных negatives. Где он не работает"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EAnthropic во внутреннем тестировании отчиталась: auto-mode определяет 83% опасных действий и блокирует их без человека. Остальные 17% проходят. На большой ночной сессии каждая пятая-шестая опасная команда добегает до Bash.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЛимит на сессию: auto-mode останавливается либо после 3 подряд отказов, либо после 20 общих отказов. На бэкенд-рефакторинге Клод легко набирает 20 отказов за час, после этого мод выключается, агент стоит. Так задумано: иначе он крутится в цикле «попробую ещё раз», пока не получит подтверждение.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСемь анти-паттернов, которые я перестал делать:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["\u003Cb\u003EЗапускать /loop на ночь без worktree.\u003C/b\u003E Один файл .git/config в проде ломает рабочую копию у всех.","\u003Cb\u003EДержать .env рядом с CLAUDE.md.\u003C/b\u003E Клод видит CLAUDE.md и читает соседние файлы. Сложи секреты в ~/.config/<project>/env.","\u003Cb\u003EПолагаться на CLAUDE.md как на permissions.\u003C/b\u003E CLAUDE.md - это контекст, а не enforcement. Issue #44868 это доказал.","\u003Cb\u003EОткрывать --dangerously-skip-permissions для «одной задачи».\u003C/b\u003E Сессия живёт час-два, агент успевает зайти в чужой контекст.","\u003Cb\u003EНе отключать MCP-серверы с записью на прод.\u003C/b\u003E Любой MCP - это новая поверхность атаки. На ночь оставляй только read-only.","\u003Cb\u003EБэкапить базу в тот же провайдер, где живёт прод.\u003C/b\u003E В PocketOS бэкапы хранились в Railway, удалить их получилось одной командой.","\u003Cb\u003EНе вести audit.jsonl.\u003C/b\u003E После инцидента непонятно, что произошло. Хук 6 решает это в три строки."],"type":"OL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EКонтр-интуитивный вывод: проблема не в --dangerously-skip-permissions. Проблема в том, что один слой защиты тренирует ложное ощущение безопасности. Слойная защита снимает 99% риска не потому, что каждый слой идеален, а потому что их четыре.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"12 пунктов, которые я прохожу перед /loop на ночь"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЭто чек-лист, который я запускаю руками перед тем, как уйти спать. Каждый пункт - одна команда или одна минута проверки.\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["git status чист, worktree изолирован: git worktree add ../night-session feature/refactor.","Бэкап прод-БД сделан в \u003Cb\u003Eдругой\u003C/b\u003E провайдер. Не в тот же Railway/Render/Coolify.","~/.claude/settings.json содержит disableBypassPermissionsMode: \"disable\" - даже если по ошибке передам флаг, агент откажется.","Все 7 хуков лежат в ~/.claude/hooks/, chmod +x стоит.","audit.jsonl пуст или ротирован - после ночи легче читать хронологию.","MCP-серверы с записью отключены: claude mcp list показывает только read-only.",".env файлы прячусь в ~/.config/<project>/env, в проекте ссылка через dotenv-cli.","Sandbox включён: sandbox.filesystem.allow указывает только ${CLAUDE_PROJECT_DIR}.","Network-allowlist ограничен api.anthropic.com + github.com + npm/pypi. Никакого *.","Прогон тестов прошёл локально без агента: npm test зелёный.","Промпт для /loop явно сужает scope: «работай только в src/billing/, не трогай миграции, не пиши в .env».","Telegram-уведомление о завершении настроено - утром виден итог без логина в систему."],"type":"OL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E12 пунктов занимают 8-10 минут, если делать впервые. После третьего раза уходит 2 минуты. Это дешевле, чем восстанавливать прод-базу из git-истории миграций.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПолный план автономной ночной сессии с примерами /goal-промптов разобрал отдельно - \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsmyslokod.ru%2Fguides%2Fgoal-mode-claude-code-codex%3Futm_source%3Dvc%26utm_campaign%3Dclaude-code-snes-prod-7-hukov%26utm_content%3Dgoal-mode-claude-code-codex&postId=2980198\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eкак запустить Claude Code и Codex на ночь через /goal\u003C/a\u003E. Там схема, при которой агент завершает 14-часовой рефакторинг без участия.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Что я бы сделал на твоём месте"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Скопируй четыре хука выше прямо сейчас. Это 15 минут. Они отрабатывают на любом проекте без правок.","Поставь disableBypassPermissionsMode: \"disable\" в ~/.claude/settings.json. Это одна строка, но она снимает 80% риска необратимых ночных команд.","Перенеси прод-бэкапы в другой провайдер. История PocketOS - про это, а не про «плохой Клод».","Не запускай /loop без worktree. Изолированная копия репо стоит ноль и спасает рабочую ветку коллег."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EИИ не удалил твою базу. Ты удалил, потому что один слой защиты тренирует ложное ощущение безопасности. К 2027 году агентский режим станет настройкой по умолчанию, и разработчики без хуков начнут терять прод чаще, чем верстальщики ломают вёрстку при мердже. Слойная защита для ночных сессий это такая же гигиена, как git под рукой.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EА что у тебя в ~/.claude/hooks/ сейчас лежит? Если ноль - какой первый хук поставишь после этой статьи?\u003C/p\u003E"}}],"customUri":"claude-code-udalil-prod-za-9-sekund-i-7-hukov-dlya-zashchity","commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"commentsSeenCount":null,"counters":{"comments":0,"favorites":1,"reposts":0,"views":622,"hits":130,"reads":null,"online":0,"timespent":null,"shares":0,"reactions":0,"total":753},"isPinned":false,"isNews":false,"ogTitle":null,"ogDescription":"Claude Code удалил прод-базу за 9 секунд, защита с хуками, предотвращение удаления, безопасность разработки, PocketOS, управление доступом, защита данных","isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"summaryContent":null,"isExistSummaryContent":false,"reactions":{"counters":[],"reactionId":0},"url":"https://vc.ru/ai/2980198-claude-code-udalil-prod-za-9-sekund-i-7-hukov-dlya-zashchity","repostData":null,"dateFavorite":0,"isFavorited":false,"warningFromEditorTitle":null,"warningFromEditor":null,"subscribedToTreads":false,"author":{"id":5977880,"name":"Артемий Миллер","nickname":"artemiy_miller","description":"Вайб кодер со стажем","uri":"/artemiy_miller","avatar":{"type":"image","data":{"uuid":"27738db1-a89b-58e7-86a2-10f831521576","width":1024,"height":1024,"size":89912,"type":"jpg","color":"d17355","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAQDAwQDAwQEAwQFBAQFBgoHBgYGBg0JCggKDw0QEA8NDw4RExgUERIXEg4PFRwVFxkZGxsbEBQdHx0aHxgaGxr/2wBDAQQFBQYFBgwHBwwaEQ8RGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhr/wAARCAAKAAoDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABwUI/8QAJhAAAQMDAgUFAAAAAAAAAAAAAQIDBAURIQAGBwgUMUESEzJhgf/EABUBAQEAAAAAAAAAAAAAAAAAAAUG/8QAHhEAAQQBBQAAAAAAAAAAAAAAAQACAxFBBAUSMcH/2gAMAwEAAhEDEQA/AKm591zqnv6bI3BVpsSpNWVEaakKQGSFn1AoHjsM9hn70207iVvdVPilNNMhJZQQ6WSS5j5fvfQtx9iMR+YFmMww01HqPSda0hASiTddj7gGF3GDe+twx2W2Y7TbLaG20ICUpSkAJAGAB4Gh49I8ONSEeqml3OEtHKAEYs9YoL//2Q=="}},"cover":{"cover":{"type":"image","data":{"uuid":"9afe9dc5-52c0-52a0-967b-4ed40a461f97","width":3712,"height":1152,"size":267737,"type":"jpg","color":"d78668","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAKAAoDASEAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABAUGB//EACgQAAECBAQFBQAAAAAAAAAAAAECBAADBRESEyEiJCUxMmFBRFFx0f/EABQBAQAAAAAAAAAAAAAAAAAAAAX/xAAaEQACAwEBAAAAAAAAAAAAAAAAAgEDERIh/9oADAMBAAIRAxEAPwDIZCaNJbq2M0qcKxKxt7lJKQRb7t6eYBcVBiHEwBqyICyARIAvr8HpBa12zPuj7X0Ksc4SiKzVxl2qr4YBZHEL2jxrpDRvWavkS+avu0e4X+woAH//2Q=="}},"cover_y":0},"achievements":[],"collectibles":[],"lastModificationDate":1785816702,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":"1ee4281e-b189-6840-aca8-c2b27ffffb1a","isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":true,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":"plus","isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":27},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":332941,"name":"AI","description":"Нейросети, искуственный интеллект, машинное обучение","uri":"/ai","avatar":{"type":"image","data":{"uuid":"47d7652c-7ff3-5ad3-b72c-3d0aa7d14f06","width":1200,"height":1200,"size":311374,"type":"png","color":"8dd2f1","hash":"2070ecd4e4745850","external_service":[]}},"cover":{"type":"image","data":{"uuid":"d830f642-8293-f95c-8c0a-cf31c79fd3aa","width":1920,"height":384,"size":110830,"type":"gif","color":"3b3846","hash":"","external_service":[],"duration":0}},"lastModificationDate":1602860409,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"ai","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"donations":{"amount":0,"isDonated":false},"isBlur":false}}],"ogTitle":null,"ogDescription":null,"isAnonymized":true}};