Advisory prompts vs enforced lifecycle
Any team running AI coding assistants for hours knows the failure modes. The agent forgets KG sync after edits. Pastes API keys into logs. Overwrites modules unread. Compacts and loses half the context. Prompting harder doesn't fix this—prompting is advisory. The model can ignore you.
The fix predates AI. Git has pre-commit and post-receive hooks since 2005. VS Code fires on open, save, close. LSP sends textDocument/didSave events. The pattern: a lifecycle event fires, your code intercepts it deterministically. The tool doesn't ask permission. It runs.
Claude Code imported that pattern. The design choice: enforcement vs suggestion. GitHub Copilot's custom instructions and Cursor's rules live in context and hope for compliance. Hooks run at execution time, separate process, full power to block.
A lifecycle taxonomy
Counting hooks misses the point. What matters: which lifecycle moments you intercept and what you do at each. Claude Code's ~20 events group into four mechanisms.
Input gating. PreToolUse fires before any tool—Bash, Edit, Write, WebFetch—and can return exit code 2 to abort. UserPromptSubmit fires before the model sees a user message, can rewrite or reject. PermissionRequest lets you approve/deny privileged ops programmatically. This is where dangerous commands get stopped cold.
Output verification. PostToolUse fires after tool success, full input/output as JSON. Can't un-run the tool, but can scan results, queue follow-up, surface warnings, write side-channel data. PostToolUseFailure fires on error—useful for logging and recovery.
Context injection. SessionStart (submatchers: startup, compact, resume), PreCompact, PostCompact, UserPromptSubmit all push information into the model's context before reasoning. This is how a session knows where it left off after compaction, or how a file edit gets relevant KG patterns injected before running.
Maintenance and accounting. Stop, StopFailure, SessionEnd, SubagentStart, SubagentStop, TeammateIdle, TaskCompleted, WorktreeCreate, WorktreeRemove, Notification—housekeeping events. Costs, metrics, desktop notifications, agent coordination, worktree cleanup live here.
Blocking vs observing
The key property: can a hook block? PreToolUse returning exit code 2 prevents the tool from running. A PreToolUse(Bash) hook pattern-matching rm -rf /, dd of=/dev/, or unquoted variables returns 2; the agent gets stderr instead of destructive shell. No prompt bypasses this—the kernel never spawns the process.
PostToolUse only observes. Runs after the fact, sees what happened, reacts: queue sync, log metric, fire notification. Can't rewind. The model is iptables INPUT vs tail -f /var/log/audit. Both useful; only one enforces.
Competitors are closing this gap slowly. Cursor 1.7 added blocking hooks. GitHub Copilot Agent's hooks observe but mostly don't block; credential scrubbing is manual setup. We ship blocking input gates and credential scrubbing on by default.
Composition pipelines
A single user action triggers a chain of hooks. Edit a knowledge note; four things happen automatically.
PreToolUse(Edit)runspre-edit-context-inject.sh, querying the KG and code graph for the target file, injecting relevant patterns into the model's context.- The Edit tool runs.
PostToolUse(Edit)runspost-file-edit.sh, routing the file:knowledge/**syncs to Weaviate KG collection,docs/**syncs to dev-docs collection, code files queue code-graph re-index.PostToolUse(Edit)also runspost-tool-security.sh, scanning new content for credentials, regenerating the KG summary if frontmatter changed.
One file edit. Four automated steps. None require the agent to remember. Pipelines like this keep agent output in sync with the rest of your system instead of drifting.
The sixteen we ship, and the env scrubbing prelude
VibeCoded Orchestrator ships twenty hooks in the free base tier, grouped by mechanism.
Security (4). A PreToolUse(Bash) hook with twenty rules for shell injection and dangerous patterns; credential scanner on every file write; SSRF guard on outbound fetches; audit logger on config changes. Each runs after env-scrubbing that unsets GITHUB_TOKEN, OPENAI_API_KEY, SUPABASE_KEY, TELEGRAM_BOT_TOKEN, AWS keys before the hook spawns any subprocess. Hooks are sandboxed by default.
Context (5). pre-edit-context-inject.sh for retrieval-augmented edits; post-file-edit.sh for KG and code-graph sync; compact-context-reinject.sh for post-compaction state; session-start-kg-loader.sh for resource paths; pre-compact-save.sh for git status and active plans.
Session (4). Stop for desktop notification and cost tracking; StopFailure for urgent alerts on errored stops; PreCompact and PostCompact for snapshot save and replay; SessionEnd for cleanup and final sync.
DX (3). Cost-tracker JSONL appender; tool-usage logger to daily JSONL; ruff and pyright in background on Python writes.
All sixteen are bash scripts. Startup cost a few milliseconds each. Read any one in under a minute, comment a line in .claude/settings.json to disable, or set VCT_DISABLE_HOOKS=1 to turn all off for a session. Auditability is not a feature—it's the price of trust.
Where this sits
| Tool | Lifecycle events | Blocking | Auto credential scrub | Open source |
|---|---|---|---|---|
| VibeCoded Orchestrator | ~20 events, 20 hooks shipped | Yes, default-on | Yes, every hook | Yes |
| Cursor (1.7+) | ~8 events | Yes | Manual | No |
| GitHub Copilot Agent | ~8 events | Mostly observing | Manual | No |
| Continue.dev | Limited | Mostly prompt-hooks | No | Yes |
| Aider | Pre/post command | Limited | No | Yes |
The twenty hooks ship with the free VibeCoded Orchestrator. Install it and security scrubbing, KG auto-sync, pre-compact snapshots, cost tracking, and credential scanning are active from the first session. Disable any one of them with a one-line change. That is the difference between an AI session you can trust and one you cannot.
Sources: