Standards: Hook and Lifecycle Conventions Across Language Rule Sets
Hook rules that shape contributor workflow across the repository's language-specific rule sets. Covers the shared baseline, per-language hook conventions, and the contributor policy by lifecycle stage.
Overview
This section documents the hook rules that shape contributor workflow across the repository's language-specific rule sets. The shared baseline defines when hooks run, how much automation is acceptable, and how TodoWrite is used to keep multi-step work visible and steerable.
The language-specific files then narrow that baseline into concrete post-edit and stop-time conventions: formatters, analyzers, build checks, and warnings that protect against risky edits such as debug prints, secret-bearing config changes, or oversized web edits.
Shared Hook Lifecycle
rules/common/hooks.md establishes the lifecycle that every other hook file extends:
- PreToolUse: runs before tool execution for validation and parameter modification.
- PostToolUse: runs after tool execution for auto-formatting and checks.
- Stop: runs when the session ends for final verification.
Permission model for automation
- Enable auto-accept only for trusted, well-defined plans.
- Disable it for exploratory work.
- Never use the
dangerously-skip-permissionsflag. - Configure
allowedToolsin~/.claude.jsoninstead.
TodoWrite as a control surface
TodoWrite is treated as a contributor control surface, not a convenience feature:
- Track progress on multi-step tasks.
- Verify understanding of instructions.
- Enable real-time steering.
- Expose mismatched task granularity, missing steps, unnecessary steps, or misread requirements.
Language-Specific Hook Rules
| File | Scope | PostToolUse behavior |
|---|---|---|
rules/common/hooks.md | Shared baseline | Defines PreToolUse, PostToolUse, Stop; auto-accept caution; TodoWrite guidance |
rules/web/hooks.md | Web-specific | Prefers project-local tooling; uses the project's existing formatter; blocks writes > 800 lines |
rules/golang/hooks.md | **/*.go, **/go.mod, **/go.sum | gofmt/goimports, go vet, staticcheck |
rules/typescript/hooks.md | **/*.ts, **/*.tsx, **/*.js, **/*.jsx | Prettier, tsc, console.log warning; Stop-time console.log audit |
rules/python/hooks.md | **/*.py, **/*.pyi | black/ruff, mypy/pyright; warns about print() statements |
rules/java/hooks.md | **/*.java, **/pom.xml, **/build.gradle, **/build.gradle.kts | google-java-format, checkstyle, compilation via ./mvnw compile or ./gradlew compileJava |
rules/kotlin/hooks.md | **/*.kt, **/*.kts, **/build.gradle.kts | ktfmt/ktlint, detekt, ./gradlew build |
rules/rust/hooks.md | **/*.rs, **/Cargo.toml | cargo fmt, cargo clippy, cargo check |
rules/swift/hooks.md | **/*.swift, **/Package.swift | SwiftFormat, SwiftLint, swift build; warns on print(), prefers os.Logger |
rules/php/hooks.md | **/*.php, **/composer.json, **/phpstan.neon*, **/psalm.xml | Pint or PHP-CS-Fixer, PHPStan or Psalm, PHPUnit or Pest; warns on var_dump, dd, dump, die(), raw SQL, disabled CSRF/session protections |
rules/perl/hooks.md | **/*.pl, **/*.pm, **/*.t, **/*.psgi, **/*.cgi | perltidy, perlcritic; warns about print in non-script .pm files, prefers say or Log::Any |
rules/csharp/hooks.md | **/*.cs, **/*.csx, **/*.csproj, **/*.sln, **/Directory.Build.* | dotnet format, dotnet build, dotnet test --no-build; Stop-time final dotnet build; warns on appsettings*.json edits |
rules/cpp/hooks.md | **/*.cpp, **/*.hpp, **/*.cc, **/*.hh, **/*.cxx, **/*.h, **/CMakeLists.txt | Build Hooks section for C++ changes |
rules/dart/hooks.md | **/*.dart, **/pubspec.yaml, **/analysis_options.yaml | dart format, dart analyze, optional flutter test after significant changes |
rules/zh/hooks.md | Chinese mirror | Restates shared hook types, auto-accept caution, and TodoWrite guidance in Chinese |
Contributor Policy by Lifecycle Stage
Before Tool Use
The shared baseline treats permissive automation as a controlled exception, not a default. The approved path is allowedTools, not dangerously-skip-permissions. Pre-tool behavior is for validation and parameter adjustment rather than output formatting.
After Tool Use
The post-tool stage is where the language-specific files do most of their work. Most rule sets use this point for formatting, linting, static analysis, and targeted compile checks, so contributors see issues immediately after a change rather than after a later manual review.
The web rules are stricter about local execution: they prefer the repository's own formatter entrypoint and reject oversized writes over 800 lines.
At Session Stop
The shared baseline reserves Stop for final verification. TypeScript adds a console.log audit. C# adds a final dotnet build and warns about edits to appsettings*.json to reduce secret leakage risk.
Security and Review Guardrails Encoded in Hooks
| Rule file | Safety check |
|---|---|
rules/common/hooks.md | Forbids dangerously-skip-permissions; routes approved automation through allowedTools |
rules/csharp/hooks.md | Warns on appsettings*.json edits to reduce secret leakage risk |
rules/php/hooks.md | Warns on debug output helpers and on raw SQL or disabled CSRF and session protections |
rules/python/hooks.md | Warns about print() in edited files; steers output to logging |
rules/perl/hooks.md | Warns about print in non-script .pm files; prefers say or logging |
rules/swift/hooks.md | Warns about print(); prefers os.Logger or structured logging |
rules/typescript/hooks.md | Warns about console.log and audits it again at session stop |
rules/web/hooks.md | Blocks writes that exceed 800 lines, keeping file-level changes reviewable |
These rules do not replace the language toolchains; they bind contributor behavior to specific checks so the edit loop stays fast, local, and auditable.
