Hooks and automation
Use this lesson to build a practical, evidence-based Nova workflow for this topic.What hooks are
Hooks are local commands that Nova runs at defined lifecycle boundaries. They are useful when a rule must be enforced mechanically rather than remembered in a prompt. Typical uses include:- rejecting unsafe tool inputs before execution;
- running local checks after selected tool calls;
- adding bounded context when a session or prompt starts;
- recording local audit signals without exposing secrets;
- notifying another local process when a lifecycle event occurs.
Supported events
Nova currently recognises these exact event names:
Event names are case-sensitive in hook paths.
Hook locations
Nova discovers hooks from:.compass/hooks/in the project;~/.compass/hooks/for personal hooks.
.yaml, .yml, and .md hook files. It also supports extensionless shebang scripts in recognised event paths. For same-source duplicates, .yaml has precedence over .yml, then .md, then an extensionless file.
Frontmatter
A configured hook can use YAML-style frontmatter followed by the command body:description— human-readable purpose;enabled— set tofalseto skip the hook;tools— tool-name glob patterns forPreToolUseandPostToolUse;timeout— process timeout in milliseconds.
match map for input-field glob matching, but the current frontmatter reader is intentionally flat and does not reliably parse nested mappings. Do not depend on match in a published hook; put input matching in the script itself.
A portable PreToolUse example
An extensionless Node.js hook avoids platform-specific shell syntax. Save this as.compass/hooks/PreToolUse/protect-env:
bash or sh locations when those interpreters are requested.
Hook input
Nova sends one event-specific JSON object to standard input. Every event includes:session_id;transcript_path;cwd;hook_event_name.
tool_name, tool_input, and tool_use_id. PostToolUse adds tool_response. Other events add their own fields, such as prompt, message, agent_id, or source.
Nova also supplies environment variables such as HOOK_EVENT, HOOK_NAME, HOOK_CWD, and tool-specific values. Prefer the JSON input because it preserves structure and is easier to validate.
Treat all hook input as untrusted. Parse JSON defensively, validate fields, quote paths, and never evaluate input as code. For malformed input, choose and document fail-open or fail-closed behaviour; the policy-enforcement example above deliberately fails closed.
Exit status and output
ForPreToolUse:
- exit code
0allows processing to continue; - a non-zero exit blocks the tool call;
- standard error, then standard output, is used as the block explanation when available.
SessionStart and UserPromptSubmit also accept successful plain-text output as additional context. Other events require the structured form for context injection.
Nova limits hook execution and output: the default per-hook timeout is 30 seconds, configured timeouts are capped at 120 seconds, and process output is bounded. Hooks should therefore be fast, local, and deterministic.
Enable or disable hooks
Hooks are enabled by default in the runtime. Configuration can explicitly change that setting:nova doctor when hook execution appears disabled or the wider installation may be unhealthy.
Design guidance
- Use
NOVA.mdfor guidance and hooks for enforcement. A hook is appropriate only when a deterministic lifecycle check is needed. - Fail closed only for high-confidence checks. A noisy
PreToolUsehook can block legitimate work. - Keep hooks quick. Long network operations make every affected tool call slower and less reliable.
- Do not print secrets. Hook output can become visible in diagnostics or injected context.
- Do not duplicate Nova approvals. Hooks can add organisation-specific constraints, but they should not weaken or work around the approval manager.
- Test scripts outside Nova first. Feed representative JSON through standard input and verify exit codes on the target operating system.
- Review project hooks after pulling changes. They are executable policy, not passive documentation.
Troubleshooting
- Confirm the directory and exact event spelling.
- Confirm the extension is supported, or that an extensionless file starts with a shebang.
- Check that the configured interpreter exists on the current machine.
- Keep paths valid for the target shell;
.yaml,.yml, and.mdbodies use the platform shell. - Verify the hook’s
toolspattern matches the runtime tool name. - Reproduce the script with captured test JSON and inspect its exit code.
- Shorten slow work or raise
timeoutonly within Nova’s cap. - Run
nova doctorto check whether hooks are disabled by configuration.