| name | Hook Register |
| description | Validates and registers hook manifest files (YAML) in the Hook Registry for versioned hook management. |
hook.register Skill
Validates and registers hook manifest files, adding them to the Hook Registry for automatic enforcement.
Purpose
While hook.define creates hooks on-the-fly and updates the live configuration (.claude/hooks.yaml), the hook.register skill formalizes this by validating a hook manifest and adding it to a versioned registry (/registry/hooks.json). This enables:
- Version Control: Track hooks as code with full history
- Review Process: Hook manifests can go through code review before activation
- Centralized Management: Single source of truth for all hooks in the organization
- Formal Schema: Ensures hooks conform to required structure
This skill is part of Betty's Layer 5 (Hooks/Policy) infrastructure, enabling automated governance and validation.
Difference from hook.define
| Feature | hook.define | hook.register |
|---|---|---|
| Purpose | Create hooks immediately | Register hook manifests for version control |
| Output File | .claude/hooks.yaml (live config) |
/registry/hooks.json (registry) |
| Use Case | Quick development, testing | Production deployment, formal tracking |
| Versioning | Not tracked | Full version history |
| Schema Validation | Basic | Comprehensive |
Usage
python skills/hook.register/hook_register.py <path_to_hook_manifest.yaml>
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
| manifest_path | string | Yes | Path to the hook manifest YAML file to validate |
Hook Manifest Schema
Required Fields
- name: Unique hook identifier (kebab-case recommended, e.g.,
validate-openapi-specs) - version: Semantic version (e.g.,
0.1.0) - description: Human-readable description of what the hook does
- event: Hook trigger event (see Valid Events table below)
- command: Command to execute when hook triggers
Optional Fields
- when: Conditional execution
pattern: File pattern to match (e.g.,"*.openapi.yaml","specs/**/*.yaml")
- blocking: Whether hook should block operation if it fails (default:
false) - timeout: Timeout in milliseconds (default:
30000) - on_failure: What to do on failure:
show_errors,silent,log_only(default:show_errors) - status: Hook status (
draftoractive, defaults todraft) - tags: Array of tags for categorization (e.g.,
["api", "validation", "compliance"])
Valid Events
| Event | Triggers When | Common Use Cases |
|---|---|---|
on_file_edit |
File is edited in editor | Real-time syntax validation |
on_file_save |
File is saved to disk | Code generation, formatting |
on_commit |
Git commit attempted | Breaking change detection, linting |
on_push |
Git push attempted | Full validation suite, security scans |
on_tool_use |
Any tool is used | Audit logging, usage tracking |
on_agent_start |
Agent begins execution | Context injection, authorization |
on_workflow_end |
Workflow completes | Cleanup, notifications, reporting |
Validation Rules
The skill performs comprehensive validation:
- Required Fields – Ensures
name,version,description,event, andcommandare present - Name Format – Validates hook name is non-empty and follows naming conventions
- Version Format – Ensures version follows semantic versioning (e.g.,
0.1.0) - Event Type – Verifies event is one of the supported triggers
- Command Validation – Ensures command is non-empty
- Type Checking – Validates
blockingis boolean,timeoutis positive number - Pattern Validation – If
when.patternis provided, ensures it's a valid string - Name Uniqueness – Checks that hook name doesn't conflict with existing hooks in registry
Outputs
Success Response
{
"ok": true,
"status": "registered",
"errors": [],
"path": "hooks/validate-openapi.yaml",
"details": {
"valid": true,
"status": "registered",
"registry_updated": true,
"manifest": {
"name": "validate-openapi-specs",
"version": "0.1.0",
"description": "Validate OpenAPI specs against Zalando guidelines",
"event": "on_file_edit",
"command": "python skills/api.validate/api_validate.py {file_path} zalando",
"when": {
"pattern": "*.openapi.yaml"
},
"blocking": true,
"timeout": 10000,
"status": "active",
"tags": ["api", "validation", "openapi"]
}
}
}
Failure Response
{
"ok": false,
"status": "failed",
"errors": [
"Invalid event: 'on_file_change'. Must be one of: on_file_edit, on_file_save, on_commit, on_push, on_tool_use, on_agent_start, on_workflow_end"
],
"path": "hooks/invalid-hook.yaml",
"details": {
"valid": false,
"errors": [
"Invalid event: 'on_file_change'. Must be one of: on_file_edit, on_file_save, on_commit, on_push, on_tool_use, on_agent_start, on_workflow_end"
],
"path": "hooks/invalid-hook.yaml"
}
}
Examples
Example 1: Register OpenAPI Validation Hook
Hook Manifest (hooks/validate-openapi.yaml):
name: validate-openapi-specs
version: 0.1.0
description: "Validate OpenAPI specs against Zalando guidelines on every edit"
event: on_file_edit
command: "python skills/api.validate/api_validate.py {file_path} zalando"
when:
pattern: "*.openapi.yaml"
blocking: true
timeout: 10000
status: active
tags: [api, validation, openapi, zalando]
Registration Command:
$ python skills/hook.register/hook_register.py hooks/validate-openapi.yaml
{
"ok": true,
"status": "registered",
"errors": [],
"path": "hooks/validate-openapi.yaml",
"details": {
"valid": true,
"status": "registered",
"registry_updated": true
}
}
Example 2: Register Breaking Change Detection Hook
Hook Manifest (hooks/prevent-breaking-changes.yaml):
name: prevent-breaking-changes
version: 0.1.0
description: "Block commits that introduce breaking API changes"
event: on_commit
command: "python skills/api.compatibility/check_compatibility.py {file_path} --fail_on_breaking"
when:
pattern: "specs/**/*.yaml"
blocking: true
timeout: 30000
on_failure: show_errors
status: active
tags: [api, compatibility, breaking-changes, commit-hook]
Example 3: Register Audit Log Hook
Hook Manifest (hooks/audit-tool-usage.yaml):
name: audit-tool-usage
version: 0.1.0
description: "Log all tool usage for compliance audit trail"
event: on_tool_use
command: "python skills/audit.log/log_tool_usage.py {tool_name} {timestamp}"
blocking: false
timeout: 5000
on_failure: log_only
status: active
tags: [audit, compliance, logging]
Integration
With Workflows
Hooks can be registered as part of a workflow:
# workflows/setup_governance.yaml
steps:
- skill: hook.register
args:
- "hooks/validate-openapi.yaml"
required: true
- skill: hook.register
args:
- "hooks/prevent-breaking-changes.yaml"
required: true
With CI/CD
Validate hooks in continuous integration:
# .github/workflows/validate-hooks.yml
name: Validate Hooks
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Validate all hooks
run: |
for hook in hooks/*.yaml; do
python skills/hook.register/hook_register.py "$hook" || exit 1
done
Loading Hooks at Runtime
Once registered, hooks can be loaded from the registry:
import json
with open('/registry/hooks.json') as f:
registry = json.load(f)
active_hooks = [h for h in registry['hooks'] if h['status'] == 'active']
Common Errors
| Error | Cause | Solution |
|---|---|---|
| "Missing required fields: name" | Hook manifest missing required field | Add all required fields: name, version, description, event, command |
| "Invalid event: 'X'" | Event type not recognized | Use one of the valid events: on_file_edit, on_file_save, on_commit, on_push, on_tool_use, on_agent_start, on_workflow_end |
| "command cannot be empty" | Command field is empty or whitespace | Provide a valid command string |
| "blocking must be a boolean" | blocking field is not true/false | Use boolean value: true or false (not string) |
| "timeout must be a positive number" | timeout is zero or negative | Provide positive number in milliseconds (e.g., 30000) |
| "when.pattern must be a non-empty string" | Pattern is empty or wrong type | Provide valid glob pattern (e.g., "*.yaml") |
Files Modified
- Registry:
/registry/hooks.json– Updated with new or modified hook entry - Logs: Hook validation and registration logged to Betty's logging system
Hook Registry Structure
The /registry/hooks.json file has this structure:
{
"registry_version": "1.0.0",
"generated_at": "2025-10-23T12:00:00Z",
"hooks": [
{
"name": "validate-openapi-specs",
"version": "0.1.0",
"description": "Validate OpenAPI specs against Zalando guidelines",
"event": "on_file_edit",
"command": "python skills/api.validate/api_validate.py {file_path} zalando",
"when": {
"pattern": "*.openapi.yaml"
},
"blocking": true,
"timeout": 10000,
"on_failure": "show_errors",
"status": "active",
"tags": ["api", "validation", "openapi"]
}
]
}
See Also
- hook.define – Use this for immediate hook creation in the dev environment (documented in hook.define SKILL.md)
- Hook Manifest Schema – See Command & Hook Infrastructure for field definitions
- Betty Architecture – Five-Layer Model for understanding how hooks fit into the governance layer
- Hooks in Claude Code – Claude Code Hooks Documentation
Exit Codes
- 0: Success (manifest valid and registered)
- 1: Failure (validation errors or registry update failed)
Best Practices
- Version Control: Keep hook manifests in your repository (
hooks/directory) - Review Process: Require code review for hook changes (they can block operations)
- Start with Draft: Register new hooks with
status: draft, test them, then promote toactive - Descriptive Names: Use clear, kebab-case names that describe the hook's purpose
- Appropriate Blocking: Only set
blocking: truefor critical validations (it will stop operations) - Reasonable Timeouts: Set realistic timeouts based on hook complexity (avoid too short or too long)
- Tag Appropriately: Use tags for easy filtering and organization
- Test Patterns: Test file patterns thoroughly to avoid unintended matches
Status
Active – This skill is production-ready and actively used in Betty's hook infrastructure.
Version History
- 0.1.0 (Oct 2025) – Initial implementation with full validation and registry management