Claude Code Hooks
Relevant source files
The following files were used as context for generating this wiki page:
Claude Code Hooks are automated scripts and configurations within the Roughly project that integrate with the Claude Code CLI to enforce project invariants, prevent accidental modifications, and ensure continuous verification of the codebase. These hooks are primarily managed via the .claude/settings.json file and executed at specific lifecycle events of a Claude session.
The project utilizes two main types of hooks: the Plan Mode Gate, which prevents pipeline execution while in Claude's internal plan mode, and the Stop Hook (verify-all), which runs structural and type-check invariants after every Claude turn. These mechanisms ensure that Roughly's gated development pipelines remain robust and that the orchestrator maintains control over the implementation process.
Sources: README.md:164-184, CLAUDE.md:65-71, skills/setup/SKILL.md:104-106
Architecture and Configuration
Claude Code Hooks are configured in the project root's .claude/settings.json file. This file maps specific Claude Code lifecycle events to executable commands, often located in the .claude/hooks/ directory.
Core Lifecycle Events
| Hook Type | Event Name | Description |
|---|---|---|
| Submission Gate | UserPromptSubmit | Fires when a user submits a prompt; used to block commands if conditions aren't met. |
| Post-Turn Hook | Stop | Fires after every completed Claude turn; used for non-blocking continuous verification. |
| Post-Tool Hook | PostToolUse | Fires after a tool is used; commonly used for auto-formatters. |
Sources: skills/setup/SKILL.md:113-132, skills/setup/SKILL.md:154-159, CONTRIBUTING.md:465-485
Hook Installation Flow
The installation of hooks is a core responsibility of the /roughly:setup skill. It handles directory creation, template substitution, and JSON merging to register hooks without destroying existing user configurations.
The diagram shows the setup logic for deploying hooks based on project maturity and required safety gates.
Sources: skills/setup/SKILL.md:104-233
Plan Mode Gate (UserPromptSubmit)
The Plan Mode Gate is a critical safety mechanism documented in ADR-009. It prevents the /roughly:build and /roughly:fix skills from being executed while Claude Code is in its internal "plan mode." This is necessary because Roughly manages its own gated pipelines and implementation subagents, which conflict with Claude's native planning state.
Implementation Details
- Script:
.claude/hooks/plan-mode-gate.sh - Registration: Registered under the
UserPromptSubmithook in.claude/settings.json. - Logic: Blocks invocation and requires the human to exit plan mode before re-invoking the skill.
Sources: skills/fix/SKILL.md:12-14, skills/setup/SKILL.md:113-132, README.md:23-29
Stop Hook (Stop)
The Stop Hook, also referred to as verify-all.sh, is a non-blocking hook that runs after every Claude turn. It serves as a continuous verification loop to catch structural drift and type-check errors as they happen.
Verification Invariants
The hook enforces several structural invariants to ensure the Roughly plugin itself remains compliant with its own design standards:
- Path Drift: Ensures agents do not reference legacy
.ruckuspaths. - Skill Line Cap: Enforces a 300-line limit for
SKILL.mdfiles. - Agent Word Cap: Enforces a 650-word limit for agent definitions.
- Pre-flight Integrity: Ensures byte-identical pre-flight blocks across hard-abort skills.
- Drift Threshold: Monitors
.roughly/known-pitfalls.mdlength for reorganization.
Sources: CONTRIBUTING.md:465-485, skills/setup/SKILL.md:164-184
Hook Execution Flow
This diagram illustrates the non-blocking nature of the Stop hook, which provides informational feedback without halting the session.
Sources: skills/setup/SKILL.md:204-209, CONTRIBUTING.md:465-470
Setup and Migration Logic
The project uses jq to safely manipulate the .claude/settings.json file. During setup or upgrade, the system follows a transactional "all-or-nothing" approach to prevent corrupting the user's settings.
Hook Conflict Resolution
When a hook (especially the Stop hook) is already present in settings.json, the setup skill offers several resolution paths:
- Add-new: Creates the hook if none exists.
- Replace: Overwrites an existing hook with the Roughly template.
- Merge: Adds the Roughly hook alongside existing hooks using the
+=operator injq. - Keep: Leaves existing hooks untouched.
Sources: skills/setup/SKILL.md:154-184, skills/upgrade/SKILL.md:300-310
Settings.json Structure Example
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": ".claude/hooks/plan-mode-gate.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": ".claude/hooks/verify-all.sh",
"timeout": 30
}
]
}
]
}
}
Sources: skills/setup/SKILL.md:113-125, skills/setup/SKILL.md:204-210
Maintenance and Drift
Hooks are subject to "drift checks" conducted by the /roughly:upgrade skill. This skill verifies:
.claude/hooks/plan-mode-gate.shis byte-identical to the source template.- The
plan-mode-gate-v1-addedmarker exists in.roughly/workflow-upgrades. - Installed agents have context-loading steps consistent with the
agent-preamble.md.
Sources: skills/upgrade/SKILL.md:240-250, skills/upgrade/SKILL.md:315-330, CONTRIBUTING.md:477-482
Claude Code Hooks provide the foundational safety layer for Roughly's complex agentic workflows. By leveraging UserPromptSubmit for gating and Stop for continuous verification, the system ensures that both the user and the AI agents adhere to project-specific constraints and architectural decisions (ADRs). These hooks transform the .claude/settings.json from a static configuration into an active participant in the development lifecycle.