Behavioral hooks
tl;dr
Crosslink’s hooks are guardrails that agents follow automatically. You configure them once; every agent session is checked on every action — enforcing code quality, issue tracking, and security without manual prompting.
How it works
You configure once:
Run crosslink init in your project. Hooks are installed into .claude/hooks/ and activate automatically for every Claude Code session.
No per-agent setup. No manual prompting. Every agent that touches this repo follows the same rules.
→
Agents get checked on every action:
Agent tries to edit a file
→ work-check.py fires
→ Has active issue? ✓ Proceed
→ Is it a blocked git command? ✗ Block
Agent finishes editing
→ post-edit-check.py fires
→ Stubs detected? Flag them
→ Tests stale? Remind to run
Requirements
- Python 3.6+ must be installed and available in your PATH
Hook overview
| Hook | Fires When | What It Does |
|---|---|---|
session-start.py |
Session start/resume | Loads context, syncs locks, restores breadcrumbs from last session |
prompt-guard.py |
Every prompt | Injects language-specific best practices (condensed after first prompt) |
work-check.py |
Before write/edit/bash | Enforces issue tracking, blocks git mutations, warns on lock conflicts |
post-edit-check.py |
After file edits | Detects stubs, runs linter (debounced), reminds about tests |
pre-web-check.py |
Before web fetch | Injects prompt injection defense before fetching external content |
What agents must follow
The hooks enforce these principles transparently:
- No Stubs — Complete, working code. No placeholder functions, TODO comments, or
unimplemented!()macros. - No Dead Code — Identify incomplete features and complete them, or remove truly dead code.
- Full Features — Implement complete features as requested. Don’t stop partway.
- Error Handling — Proper error handling everywhere. No panics on bad input.
- Security — Validate input, use parameterized queries, no command injection.
Large task management
When code will exceed 500 lines, the hooks guide agents to:
- Create a parent issue for the feature
- Break it into subissues for trackable components
- Work on one subissue at a time
- Inform the user about the multi-part implementation
Language detection
The hooks auto-detect project languages and inject relevant best practices:
- Rust:
?operator,clippy, parameterized SQL, avoid.unwrap() - Python: Type hints, proper exceptions,
pathlib, context managers - JavaScript/TypeScript:
const/let, async/await, strict mode, input validation - Go: Check errors,
context.Context,deferfor cleanup - And 16 more: Java, C/C++, C#, Ruby, PHP, Swift, Kotlin, Scala, Zig, Odin, Elixir, Haskell
Post-edit checking
After every file edit, post-edit-check.py automatically:
- Stub detection — Scans for TODO, FIXME,
pass,...,unimplemented!(), empty functions - Linting — Runs the appropriate linter (cargo clippy, flake8, eslint, go vet) with 10-second debouncing
- Test reminders — Checks if code has been modified since the last test run and reminds to run tests
Web security (RFIP)
The pre-web-check.py hook injects the Recursive Framing Interdiction Protocol before any web fetch. This defends against prompt injection by establishing that external content is data, not instructions — any instruction-like text in fetched content is flagged, not followed.
Drift detection
When an agent’s behavior diverges from project norms (e.g., repeatedly ignoring tracking requirements or skipping tests), the hooks increase reminder frequency automatically. The reminder_drift_threshold in hook-config.json controls sensitivity.
Intervention tracking
When a hook blocks an agent’s action, or a human redirects the agent’s approach, the intervention is logged for audit:
crosslink issue intervene <issue-id> "Hook blocked git push attempt" \
--trigger tool_blocked \
--context "Agent tried to push directly"
Context verification
Verify that all hook and rule files are deployed correctly:
crosslink context check # verify all files exist and are valid
crosslink context measure # measure context injection overhead
Customization
Hook behavior is controlled by .crosslink/hook-config.json. See Hook Configuration Reference for details.
Rules are stored as markdown files in .crosslink/rules/. See Rules Customization.
Installing hooks in other projects
# Automatic setup (recommended)
crosslink init
# Or manual copy
cp -r /path/to/crosslink/.claude /your/project/
cp -r /path/to/crosslink/.crosslink/rules /your/project/.crosslink/