Týmy přidávají Claude Code hooky, aby AI agenti nemohli napáchat škodu, a pak předpokládají, že fungují. Naše procházely při každém běhu a přitom nedělaly nic. Hook, který potichu nedělá nic, je horší než žádný, protože se na něj všichni přestanou dívat. Oprava jsou čtyři levné kontroly, které si může zkopírovat každý tým.
Krátká odpověď: hook zmlkne, když jeho výstup nikam nejde, když jeho cesta neexistuje nebo když někdo přepíše jeho exit kód. Všechny tři věci kontrolujte v CI. A hook, na kterém záleží nejvíc, dejte na událost Stop, aby agent nemohl říct „hotovo“, dokud jsou testy červené.
Jak Claude Code hooky vůbec něco blokují?
Hook je příkaz shellu, který Claude Code spustí při události. PreToolUse běží před voláním nástroje, Stop, když chce agent skončit. Příkaz dostane událost jako JSON objekt na stdin.
Rozhoduje exit kód:
Exit 0 pustí dál.
Exit 2 zablokuje. To, co hook zapsal do stderr, jde zpět agentovi jako důvod.
Jakýkoli jiný kód je neblokující chyba. Claude Code pokračuje.
To je celá dohoda. Všechno, co se nám rozbilo, se rozbilo uvnitř ní.
Proč naše hooky nedělaly nic?
Dva hooky v naší firemní konfiguraci mlčely týden, od prvního dne. Tři příčiny, každá sama o sobě neškodná:
Umlčený. Oba psaly svou jedinou zprávu do stderr. Příkaz v nastavení končil 2>/dev/null. Agent neslyšel ani slovo.
Chybějící. Oba používaly relativní cestu. V session spuštěné ve vnořeném repozitáři cesta neexistovala. Exit 127, příkaz nenalezen.
Zamaskovaný.|| true na konci změnilo 127 na 0. U blokující události stejně změní 2 na 0. Každý běh „prošel“.
Nikdo si toho nevšiml, protože hook, který mlčí, vypadá přesně jako zdravý. Našli jsme to až při analýze vlastních Claude Code sessions.
Do našeho validátoru jsme přidali kontrolu, která běží v CI našich repozitářů. Čtyři grepy nad .claude/settings.json, nic se nespouští:
Kontrola
Co odhalí
Oprava
Skript existuje
Cestu, která neexistuje
"$CLAUDE_PROJECT_DIR"/... nebo absolutní cesta
Skript je spustitelný
Hook, který běží jen náhodou
chmod +x
stderr se nezahazuje, když do něj skript píše
Umlčený hook
Odstranit 2>/dev/null
PreToolUse hook nekončí || true
Blok přepsaný na průchod
Odstranit || true
Kontrolu jsme otestovali na skutečné chybě. Stará konfigurace hlásila kritické chyby, opravená prošla.
Ne každé || true je chyba. Náš uvítací hook běží na SessionStart s 2>/dev/null || true schválně. Pozdrav nesmí nikdy shodit session. Kontrola to hlásí jen tam, kde se čeká blok.
Ponaučení v jedné větě, jak ho máme v hooku proti AI podpisům: „A rule is a request. This is the lock.“ Pravidlo je prosba, hook je zámek. A zámek potřebuje vlastní test.
Ještě nedávno měl agent pravidla jen v rules souborech a někdy je nedodržel. Tak jsme z nich udělali kontroly, které se nedají obejít.
Filip Papranec
zakladatel Digitaliko
Který hook opravdu hlídá?
Stop hook. Agent, který řekne „hotovo“, dokud jsou testy červené, stojí seniora jedno kolo review. Stop hook ho donutí nejdřív to opravit.
Naše verze z veřejného starteru, mírně zkrácená:
#!/bin/bash
# Stop hook: the agent can't finish while the checks are red.
in=$(cat)
[ "$(printf '%s' "$in" | jq -r '.stop_hook_active // false')" = true ] && exit 0
cd "${CLAUDE_PROJECT_DIR:-.}" 2>/dev/null || exit 0
out=$(GATE_SKIP_INSTALL=1 GATE_SCRIPTS="typecheck lint test" bash scripts/gate.sh checks 2>&1) && exit 0
jq -n --arg r "Checks are red. Fix them before you say the task is done:
$out" '{decision: "block", reason: $r}'
Krok po kroku dělá tohle:
01
Přečte stop_hook_active
Když je true, agent už pokračuje kvůli tomuto hooku. Hook ho pustí, aby se netočil donekonečna.
02
Spustí kontroly
Typecheck, lint a testy, stejné jako v CI.
03
Zablokuje s důvodem
Při červených kontrolách vrátí decision: block a jako důvod log chyby.
04
Agent opraví příčinu
Přečte log, opraví chybu a zkusí skončit znovu.
Blokuje JSON odpovědí, ne exit kódem. Agent tak pracuje dál a důvod, který dostane, je přesně to, co selhalo.
Je to včasné varování, ne brána. V naší smyčce agenta běží rozhodující kontrola znovu po session, v kódu, na který agent nedosáhne. Hook jen ušetří jedno kolo.
Co se rozbilo v našem vlastním Stop hooku?
Stop hook naší smyčky měl vlastní tichou chybu. Nastavoval pevný, minimální PATH bez uživatelských adresářů s nástroji, a v repozitářích na Bunu chyběly nástroje, které kontroly potřebují. Bránu navíc hledal na jednom pevném místě, které existovalo jen na stroji agenta. Jeden PR opravil obojí: plný PATH a bránu hledá relativně k samotnému hooku.
Claude Code hooky pro tým: kde začít?
Projděte si, co z toho vaše repozitáře už mají. Každý bod je pár řádků v nastavení nebo v CI:
Nejsnáz se přehlédne třetí bod. Náš hook proti AI podpisům čte vstup přes jq, pak zkusí python3, pak sed. Chybějící jq nesmí ze zámku udělat tiché povolení. Relativní cesty se zase rozbijí ve vnořených repozitářích a worktree.
Chcete hooky, které ve vašich repozitářích opravdu drží?
Hooky, brány a CI nastavujeme přímo v repozitáři týmu v rámci služby AI-native SDLC pro vývojové týmy. Chybí vašemu týmu spíš ruce než pravidla? Podívejte se na seniorního vývojáře do týmu. AI dnes píše veškerý náš kód a za výsledek ručí senior. Od roku 2023 jsme dodali 15+ produkčních projektů.
Ozveme se do dvou pracovních dnů a společně vybereme, co vyřešíme jako první.
Příkazy shellu, které Claude Code spustí při události, třeba PreToolUse před voláním nástroje nebo Stop, když chce agent skončit. Hook dostane událost jako JSON na stdin a rozhodne exit kódem nebo JSON odpovědí.
Jak Claude Code hook zablokuje příkaz?
Exit kódem 2. Claude Code pak akci zablokuje a to, co hook zapsal do stderr, vrátí agentovi jako důvod. Exit 0 ji pustí. Jakýkoli jiný kód je neblokující chyba a agent pokračuje.
Proč můj Claude Code hook neběží?
Nejčastěji kvůli relativní cestě, která v adresáři session neexistuje, kvůli stderr zahozenému přes 2>/dev/null nebo kvůli || true na konci, které přepíše exit kód. Cestu začněte "$CLAUDE_PROJECT_DIR" a konfiguraci hooků kontrolujte v CI.
Co znamená stop_hook_active?
Je true, když agent už pokračuje proto, že ho Stop hook zablokoval. Když je true, skončete hned. Jinak ho kontrola, kterou agent neumí opravit, blokuje donekonečna.
Stačí Stop hook jako brána kvality?
Ne. Je to včasné varování uvnitř session. Stejné kontroly pusťte znovu v CI a v ochraně větve, kde je agent nemůže změnit.
Zeptejte se AI na tento článek
AI při odpovědi využije i naše další články a zkušenosti z reálných projektů.
Playwright MCP dává AI agentovi skutečný prohlížeč. Jak ho používáme, aby agent ověřil svou změnu v běžící aplikaci a vrátil PASS nebo FAIL se screenshoty, co tím chytíme oproti unit testům a kdy jsou lepší obyčejné Playwright skripty.
LLM as a judge znamená, že jazykový model hodnotí práci jiného modelu podle sepsaných kritérií. Jak ho používáme na každém pull requestu našeho AI agenta: nejdřív strojové kontroly, pak čerstvá session jen pro čtení, která má práci vyvrátit, typovaný verdikt a pravidla, která přibyla po jeho chybách.
Jak děláme AI code review s Claude Code na každém pull requestu jednou sdílenou GitHub Action: co má AI recenzent hledat, jak bylo zelené a mlčelo, co přehlédne a proč schvaluje jen člověk.