Companion to the ### Hook registry section in CLAUDE.md. Full enforcement list lives here because the inline form was pushing CLAUDE.md past the 40 KB cap.
.claude/hooks/fleet/<name>/— fleet-canonical hooks. Edited only insocket-wheelhouse/template/.claude/hooks/fleet/<name>/; cascade pushes to every fleet repo. Citation gate (new-hook-claude-md-guard) requires each hook to have a matching(enforced by ...)mention somewhere in CLAUDE.md or the linked fleet docs..claude/hooks/repo/<name>/— host-repo-only hooks. Live in the downstream repo; exempt from the citation gate. Mirrorsdocs/agents.md/repo/+scripts/repo/..claude/hooks/fleet/_shared/— utilities imported by hooks (transcript.mts,stop-reminder.mts,shell-command.mts,acorn/, etc.). Also fleet-canonical.
The fleet hooks each cite their own trigger + bypass surface in their README.md. They are:
actionlint-on-workflow-edit— runs actionlint when.github/workflows/**is editedanswer-questions-reminder— surface unanswered transcript questionsanswer-status-requests-reminder— surface status pings before silent end-of-turnauth-rotation-reminder— reminds about expiring keychain tokensavoid-cd-reminder— keepscdout of Bash, use{ cwd }insteadbroken-hook-detector— SessionStart probe for sibling hooks with missing importsc8-ignore-reason-guard— blocks a c8/v8 coverage-ignore directive with no reasonchangelog-entry-shape-nudge— PreToolUse Edit/Write, non-blocking. Warns when aCHANGELOG.mdedit adds a column-0 entry bullet that links no detail intodocs/agents.md/{fleet,repo}/<topic>.md. A CHANGELOG entry is a one-line bullet with the rationale linked to an agents.md doc (same diet pattern as the CLAUDE.md card); inline prose drifts from the doc. Sub-bullets/headings ignored. No bypass (never blocks)claude-md-rule-add-guard— blocks hand-adding a CLAUDE.md rule; routes it throughscripts/fleet/codify-rule.mts(which writes the terse bullet within the 40KB cap + theagents.md/{fleet,repo}/detail doc via the AI helper)clone-reviewed-repo-nudge— PreToolUse(Bash), non-blocking. Nudges when reviewing/cloning an external (non-SocketDev) GitHub repo toward the standard reference-clone dir (~/.socket/_wheelhouse/repo-clones/<org>-<repo>/, viagetSocketRepoClonesDir()) and the smallest-practical clone flags (--depth=1 --single-branch --filter=blob:none). Two arms: agh repo view/--repoof an external repo, and agit cloneof an external repo missing those flags. No bypass (never blocks)codex-no-write-guard— blockscodexinvocations with write-intent flagscommit-author-guard— canonical-identity gate on git author emailconcurrent-cargo-build-guard— blocks a secondcargo build --releasewhile one is in flight (an OOM guard). Capability-gated via the@socket-capability cargoheader, so the cascade installs it only in repos declaringclaude.capabilities: ["cargo"].dirty-worktree-stop-guard— Stop-time: BLOCKS ending a turn with a dirty PRIMARY checkout (uncommitted/untracked/staged-but-uncommitted). Escapes: clean tree, a linked git worktree (defer viagit commit --no-verifythere), orAllow dirty-worktree bypass. Once-per-turn (suppressed whenstop_hook_active); fail-open.dogfood-cascade-reminder— Stop-time: edited template/ but the dogfood copy is stale → cascadeenterprise-push-reminder— GitHub enterprise ruleset push-property remindersextension-build-current-reminder— pairstools/.../extension/src/**edits with a buildfile-size-reminder— Stop-time scan for source files over the 500-line soft capinline-script-defer-guard— blocks<script>withoutdefer/async/modulejudgment-reminder— perfectionist / direct-imperative / queue-completion nudgesmass-delete-guard— blocks a commit deleting ≥50 files or >75% of the tree (clobbered index)no-amend-foreign-commit-guard— blocksgit commit --amendonto an unpushed commit not authored this turn (a parallel session's work); bypassAllow amend-foreign bypassno-blanket-file-exclusion-guard— blocks amax-file-lines:exemption marker that names a self-judgment word (legitimate,ok, …) instead of a real category; no bypassno-blind-keychain-read-guard— blocks Bash reads of platform keychain tokensno-cascade-transient-git-guard— blocks cascade commits on a cherry-pick/detached/rebase HEADno-direct-linter-guard— PreToolUse Bash: blocks invoking a linter/formatter binary directly (oxlint/oxfmt/eslint/prettier/biome/dprint/rustfmt/gofmt, thenode_modules/.bin/path form, andcargo fmt/cargo clippysubcommands), matched on basename via AST parse. The fleet runs lint/format only through the script wrappers (pnpm run lint/fix/check/format,scripts/fleet/*), which own the-c .config/fleet/…flag plus ignore set. A bare formatter is configless (corrupts files) and unscoped (reformats vendoredupstream/). BypassAllow direct-linter bypassno-empty-commit-guard— blocks--allow-emptycommits without bypassno-env-kill-switch-guard— blocks adding adisabledEnvVar/SOCKET_*_DISABLEDkill switch to a hookno-ext-issue-ref-guard— blocks<owner>/<repo>#<num>from non-SocketDev orgsno-orphaned-staging— blocks ending a turn with staged-but-uncommitted hunksno-other-linters-guard— PreToolUse Edit/Write: fleet uses oxlint + oxfmt ONLY. Blocks creating a biome/eslint/prettier/dprint config file or adding@biomejs/biome/eslint/@eslint/*/@typescript-eslint/*/prettier/dprint/rometo apackage.json. Vendored upstream (upstream/,vendor/,*-upstream) exempt. Committed-state gate:scripts/fleet/check/only-oxlint-oxfmt.mts. BypassAllow other-linter bypassno-pkgjson-pnpm-overrides-guard— keeps overrides inpnpm-workspace.yamlno-pm-exec-guard— blocks<pm> exec(wrapper overhead) +npx/pnpm dlx/yarn dlx(fetch+exec) Bash invocations; bypassAllow pm-exec bypassno-platform-import-guard— blocks direct/nodeor/browserimports of platform-split modules (http-request, logger); bypassAllow platform-http-import bypassno-premature-commit-kill-guard— PreToolUse Bash: blocksrun_in_background:trueon agit commit/rebase/merge/cherry-pick(its bounded ~60s pre-commit looks like a hang when backgrounded), and blocks apkill/killtargeting agit commit/git push, apre-commit/pre-pushhook process, or avitestrun (killing a mid-hook run corrupts the index + leaks workers; a broad bare-verb pattern also reaps a parallel session's op in a sibling checkout). The worker-scoped reapvitest/dist/workersis exempt. BypassAllow background-git bypassno-test-in-scripts-guard— blocksnode:testsuites underscripts/(they never run in CI; move totest/unit/vitest)options-param-naming-guard— PreToolUse Edit/Write: blocks introducing a function options-bag param namedoptsinto a code file (the param isoptions, the normalized local isopts). AST-parsed via_shared/acorn(no regex; the parser handles TS). Edit-time half of the pair with thesocket/options-param-naminglint rule. Skips.d.ts+ test files; per-line marker// socket-lint: allow options-param-naming; bypassAllow options-param-naming bypassprefer-json-clone-guard—JSON.parse(JSON.stringify(x))overstructuredCloneno-token-in-dotenv-guard— blocks raw token writes into.env*/.envrcno-unisolated-git-fixture-guard— blocks a test that spawnsgitagainst a temp-dir fixture without isolation. Under pre-commit the inheritedGIT_DIR/GIT_WORK_TREEleaks the fixture's writes onto the live.git/config(setscore.bare/junk identity, stacks junk commits). Satisfy it with the blessed one-linerimport '.git-hooks/_shared/isolate-git-env.mts'(strips the discovery vars on load; vitest does this via its setup) or by pinningGIT_CONFIG_GLOBALper-spawn. BypassAllow unisolated-git-fixture bypassno-verify-format-reminder— PreToolUse Bash, non-blocking. On agit commit/push --no-verify(theAllow no-verify bypasspath) it runsoxfmt --checkon the changed format-relevant files and warns about any that are unformatted. Rationale:--no-verifyskips the format gate too, so the debt would otherwise ship and fail CI. The message names the files plus theoxfmt -c .config/fleet/oxfmtrc.json <files>fix. Silent forFLEET_SYNC=1cascade commits.node-modules-staging-guard— blocks stagingnode_modules/into gitparallel-agent-edit-guard— blocks edits to files another agent owns this sessionpath-guard— blocks multi-stage paths constructed outsidepaths.mtspaths-mts-inherit-guard— sub-packagepaths.mtsmustexport *from parentplugin-patch-format-guard—# @-header + plaindiff -ubody for plugin patchespointer-comment-reminder— limits one-line "see X" pointer comments per filepr-vs-push-default-reminder— direct-push-to-main vs. PR-only-on-rejection nudgeprefer-rebase-over-revert-reminder— rebase unpushed commits, don't revertprimary-checkout-branch-guard— blocksgit checkout/switch <branch>/-b/-cin the primary checkout (branch work goes in a worktree); bypassAllow primary-branch bypassprivate-name-reminder— blocks private repo / company names in public surfaceclaude-lockdown-guard— headlessclaude/codex execmust set the lockdown flagsprose-antipattern-guard— PreToolUse block on AI prose tells (em-dash chains, throat-clearing, "not X it's Y", hedging adverbs) in CHANGELOG.md / docs/**/*.md / README.md; bypassAllow prose-antipattern bypassyakback-reminder— merged Stop scan: teacher-tone comments + "the user" naming + speed-vs-depth choice menus + self-narration (status-recap padding, "now let me" openers, hedges, apology-padding); per-group disable env vars preservedprovenance-publish-reminder—--stagedprovenance lifecycle reminderpublic-surface-reminder— Linear refs / private names / external issue refspull-request-target-guard—pull_request_target+ fork-head checkout patternscan-label-in-commit-guard— strips Socket scan labels from commit messagessetup-basics-tools— SessionStart installer for baseline dev toolingsetup-claude-scanners— SessionStart installer for the Claude scanner toolchainsetup-firewall— SessionStart installer/starter for Socket Firewallsetup-misc-tools— SessionStart installer for miscellaneous fleet toolssocket-token-minifier-start— auto-starts the token-minifier proxy fail-closedstale-process-sweeper— Stop-time reaper for orphaned vitest workerssweep-ds-store— Stop-time.DS_Storeremoval (no bypass)synthesized-script-edit-guard— blocks editing a cascade-synthesizedpackage.jsonscriptsentry (lives inCANONICAL_SCRIPT_BODIES) directly, since the next cascade reverts it; edit the manifest + cascade instead. Bypass:Allow synthesized-script-edit bypasstest-platform-coverage-reminder— nudges to gate POSIX-vs-Windows path assertions in test editstoken-guard— redacts tokens/keys/JWTs in tool outputunbacked-claim-commit-guard— blocksgit commit/pushwhen the last turn claimed "tests pass"/"builds"/"typechecks"/"lint passes"/"render verified" with no backing command this session (shares the matcher withstop-claim-verify-reminder). Bypass:Allow unbacked-claim bypassuncodified-lesson-reminder— Stop-time: the turn wrote afeedback/projectmemory with an enforceable shape + no enforcer citation → nudge to codify it via/codifying-disciplinesorscripts/fleet/codify-rule.mts. Scoped to the memory-write signal so it doesn't overlapcompound-lessons-reminder. Non-blocking, no bypass.uses-sha-verify-guard— full-SHA reachability check foruses:pinsversion-bump-order-guard— version bump → CHANGELOG → tag orderingvitest-vs-node-test-guard— vitest vs node-test runner separationworkflow-uses-comment-guard— SHA-pinneduses:lines need# <tag> (YYYY-MM-DD)workflow-multiline-body-guard—gh ... --body-fileover inline--body "..."
Tooling + package manager:
no-strip-types-guard— blocks--experimental-strip-typesno-tail-install-out-guard— blocks piping install/check/test/build totail/head(hides SFW warnings)prefer-pipx-over-pip-guard— blockspip/pip3; usepypa-toolorpipx install <pkg>==<ver>reserved-script-dir-guard— blocks build/output dir names underscripts/; bypassAllow reserved-script-dir bypassnpm-otp-flow-reminder— npm 2FA registry ops need an interactive-TTY OTP (run in a real terminal)
Supply-chain hygiene:
check-new-deps— Socket-scores newly added dependencies at edit timeminimum-release-age-guard— enforces the 7-day soak on new depssoak-exclude-date-guard— a soak-bypass entry needs a# published: … | removable: …annotationsoak-exclude-scope-guard— soak-exclude entries are exact-pin + scopedno-pkgjson-pnpm-overrides-guard— version-range pins go inpnpm-workspace.yamloverrides:, notpackage.jsonbundle-flags-guard— guards bundler trust/exotic-subdep flagscatch-message-guard— keeps catch-block error messages thoroughnpmrc-trust-optout-guard— blocks the pnpm trust-aware env-expansion opt-out (PNPM_CONFIG_NPMRC_AUTH_FILE/NPM_CONFIG_USERCONFIG) +${ENV}-beside-_authTokenin a committed.npmrctarget-arch-env-guard— guards cross-arch build env varstrust-downgrade-guard— blocks weakening atrustPolicy/trust-all/blockExoticSubdepsgate
Prompt-injection + agent-DoS:
prompt-injection-guard— flags agent-overriding text in deps/upstreams/fixtures/fetched docsai-config-poisoning-guard— blocks.claude/.cursor/.gemini/.vscodewrites that bypass a guard, exfiltrate, or store tokens off-keychainai-config-drift-reminder— Stop-time nudge on AI-config driftclaude-code-action-lockdown-guard— enforces Agents-Rule-of-Two on CI agent workflowsno-shell-injection-bypass-guard— blocks allowlist-evasion shell constructs (=cmd,<()/>()/=(), zsh-module builtins); bypassAllow shell-injection bypassproc-environ-exfil-guard— blocks reads of/proc/*/environ-style secret exfiluntrusted-coauthor-guard— blocks aCo-authored-by:trailer crediting an identity not on the cascadedgit-authors.jsonallowlist (a drive-by issue/PR from a new low-history account is untrusted input, not a contributor to auto-credit); bypassAllow untrusted-coauthor bypass
The set drifts; the citation gate (new-hook-claude-md-guard) catches additions that ship without a CLAUDE.md reference.