Skip to content

Hooks

Hooks are scripts the agent runtime fires at well-defined points in the conversation: before a tool runs, after a tool succeeds, when a tool fails, when the session starts, when context is compacted, when the conversation stops. Octopus ships a curated set of hooks that attach automatically in any repo with hooks: true in .octopus.yml (the default for the quality bundle and common in starter).

Why hooks live below skills

Skills tell the agent how to do things β€” instructions in prose. Hooks tell the runtime what to do regardless of the agent β€” deterministic shell scripts. The split matters: a skill that says β€œdon’t run rm -rf” can be talked out of by a clever prompt; a hook that exits non-zero on rm -rf cannot. Hooks are the layer where Octopus enforces guarantees that hold whether the agent is Claude Code in bypassPermissions mode, Copilot, Codex, Gemini, or OpenCode.

The flip side: hooks add latency to every tool call they attach to, so the set stays small and each hook short-circuits aggressively (checks one thing, exits fast).

Lifecycle phases

PhaseWhen it firesStop on non-zero?
session-startConversation beginsNo β€” output is added to context
pre-tool-useBefore any tool callYes β€” blocks the call
post-tool-useAfter a tool succeedsNo β€” advisory
post-tool-use-failureAfter a tool failsNo β€” advisory
pre-compactBefore context compactionNo β€” output saved as state
post-compactAfter compaction completesNo β€” output added to new context
stopConversation endsNo β€” advisory
session-endSession terminatesNo β€” advisory
git pre-pushNative git hook on git pushNo β€” advisory

Installed hooks

Hooks that have rationale worth a page of their own get one (linked in the table). The rest are listed for completeness.

HookPhaseWhat it doesDetail
destructive-guardpre-tool-useBlocks rm -rf, git push --force, DROP TABLE, DELETE FROM without WHERE, chmod -R 777, curl | bash, etc. Bypass via # destructive-guard-ok: <reason> marker.β†’
detect-secretspre-tool-useScans staged files for hardcoded API keys, JWTs, Stripe/SendGrid/Slack/GitHub tokens before commit. Exits 2 to block.β†’
block-no-verifypre-tool-useRefuses git commit --no-verify and git push --no-verify. Pre-commit hooks exist for a reason.β€”
format-checkpre-tool-useVerifies the project formatter would not reformat the file the agent is about to write.β€”
git-push-reminderpre-tool-useOne-time reminder to self-review the diff before pushing.β€”
auto-formatpost-tool-useAuto-runs the project formatter on every Write/Edit based on file extension. Idempotent; never fails the hook.β†’
typecheckpost-tool-useRuns tsc --noEmit, dotnet build, mypy, etc. after edits to surface type regressions before the next prompt.β†’
console-log-warnpost-tool-useWarns when console.log / print() lands in a non-test file.β€”
console-log-checkstopFinal sweep for debug statements left behind.β€”
mcp-healthpost-tool-use-failureDetects MCP server outages and prints a one-line diagnosis instead of letting the agent retry blindly.β€”
propose-knowledge-updatestopScans the session transcript for corrections, re-reads, re-greps; writes a proposal to .octopus/proposals/<ts>.md for human review.β†’
grounding-checkstopFires at task end with an uncommitted diff; queues a signal-only grounding review (invented conventions, unsupported domain facts) to .octopus/proposals/.β†’
load-contextsession-startLoads ~/.octopus/state/pre-compact.yml and surfaces it as initial context.β€”
save-statepre-compactCaptures session metadata before compaction so the next session starts informed.β€”
reload-contextpost-compactReattaches relevant state after compaction discards mid-turn buffers.β€”
lifecycle-markersession-endRecords session boundaries for downstream tooling.β€”
rules-syncgit pre-push (custom)Verifies the project’s rules tree matches the manifest before pushing.β€”
pre-push-audit-suggestgit pre-pushAdvisory: inspects the diff and prints which Octopus audit skills (audit-security, audit-money, etc.) are relevant. Never blocks the push.β†’

Opting out

Two levels of granularity:

# Disable the whole hooks layer
hooks: false
# Keep hooks but disable the destructive guard specifically
hooks: true
destructiveGuard: false

Other hooks can be removed individually by editing the generated .claude/settings.json after octopus setup, but that drifts from the manifest β€” prefer asking for a manifest opt-out flag if you find yourself doing it repeatedly.

Agent coverage

Hooks are a Claude Code platform feature. For Copilot, Codex, Gemini, and OpenCode, Octopus inlines equivalent rules from rules/common/quality.md and rules/common/security.md into the generated configuration β€” same intent, weaker enforcement, since those agents have no runtime layer that can refuse a tool call.

Source: hooks/