Architecture
Dispatcher flow and system design
Overview
klaudiush is a Go binary that acts as a validation dispatcher. Claude Code sends hook events as JSON to stdin, klaudiush validates the operation through a pipeline of matchers and validators, and returns a JSON response to stdout. The whole process runs synchronously in under 115ms1.
Claude Code JSON → CLI → JSON Parser → Dispatcher → Registry → Validators → Result Dispatcher flow
The dispatcher orchestrates the validation pipeline:
- Parse the JSON hook event into a
hook.Context - Check exception tokens - if valid, convert block to warning
- Query the registry for validators matching this context
- Run matched validators and collect results
- Build the JSON response with error codes, messages, and fix hints
The response always exits 0 (except crashes which exit 3). Blocking is communicated
via permissionDecision: "deny" in the JSON output rather than exit codes.
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "[GIT001] Missing signoff flag. Add -sS to your commit command.",
"additionalContext": "..."
},
"systemMessage": "..."
} Validator registry
Validators register themselves with predicates that describe what events they handle. The registry matches incoming events against these predicates and only runs relevant validators.
| Predicate | Matches |
|---|---|
EventTypeIs | Hook event (PreToolUse, PostToolUse, Notification) |
ToolTypeIs | Tool name (Bash, Write, Edit) |
CommandContains | Command substring |
FileExtensionIs | File extension (.md, .tf, .go) |
FilePathMatches | File path pattern |
| Composable | |
And(p1, p2) | Both must match |
Or(p1, p2) | Either matches |
Not(p) | Inverts match |
Each validator returns a Result with a status (Pass, Fail, Warn), an error
code, a human-readable message, and a fix hint. Error codes map to documentation pages
at /e/CODE.
Built-in validators
| Category | Validators |
|---|---|
| Git | commit, push, PR, branch, add, no-verify, fetch, merge |
| File | markdown, shellscript, terraform, workflow, gofumpt, python, javascript, rust |
| Secrets | 25+ regex patterns, optional gitleaks |
| Shell | backtick detection (legacy and comprehensive modes) |
| Notification | bell (ASCII 7 to /dev/tty for dock bounce) |
Parallel execution
Validators run independently and don't share state. The dispatcher collects all results before building the response. File validators that call external tools (shellcheck, terraform fmt, actionlint) have configurable timeouts to prevent hanging.
Parser system
klaudiush includes parsers for bash commands and git operations. The bash parser uses mvdan.cc/sh for AST parsing - it understands redirects, pipes, subshells,
and command substitution at a structural level rather than with regex. The git parser
extracts commands, flags, and arguments from git CLI invocations.
Config loading
Configuration uses koanf for hierarchical loading with deep merge. Sources
load in order (defaults, global config, project config, env vars, CLI flags) and merge
with later sources winning on conflict. The full load completes in under 45 microseconds.
- klaudiush/
- cmd/klaudiush/ - CLI entry point
- pkg/
- hook/ - Event types, Context
- parser/ - Bash/Git/command parsing
- config/ - Configuration models
- logger/ - Structured logging
- internal/
- dispatcher/ - Validation orchestration
- validator/ - Validator interface, registry
- validators/ - All validator implementations
- git/ - Git-specific validators
- file/ - File format validators
- secrets/ - Secret detection
- shell/ - Shell command validators
- notification/ - Notification validators
- rules/ - Dynamic validation rules
- exceptions/ - Exception workflow
- config/ - Configuration loading
- doctor/ - Diagnostic system
- backup/ - Config backup system