> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cogniagent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Hooks

> Run your own checks and automations at key moments in a task — validation, formatting, guardrails, and audit trails.

Hooks let a worker run your own commands at defined moments in the [agentic loop](/cowork/loop/agentic-loop) — before a tool runs, after it runs, or when the turn stops. Use them to validate input, auto-format output, block risky actions, or log activity for review, without changing the worker's instructions.

## What a hook is

A hook is a small command — typically a shell command or script — that the worker runs automatically at a specific moment, instead of something you trigger by hand. You author hooks once, as a worker file, and every task that worker runs picks them up.

Hooks live in a `hooks.json` file at the worker's file scope, alongside its [Skills](/cowork/workers/skills), worker instructions, and memory. Because they're worker files, you can edit them yourself through the Files panel, or ask the worker to write them for you.

<Note>
  This is the deliberate exception to how a [worker's definition](/cowork/workers/overview) otherwise works: a running task pins the worker's instructions, model, and connections as a snapshot for its whole lifetime, but hooks are read live at the start of every turn instead. If you fix a broken hook mid-task, the very next turn picks up the fix. A worker-less task has no worker file scope, so it has no hooks.
</Note>

## When hooks fire

Hooks attach to named events in the loop. Each event fires at a precise point, and each has a different amount of power over what happens next.

| Event             | Fires                                                                | Matches against                                                                                                                        | Can do                                                                          |
| ----------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| **PreToolUse**    | After a tool call is already approved, right before it executes      | Tool name                                                                                                                              | Block the call (the worker sees why)                                            |
| **PostToolUse**   | After a tool call finishes, before its result is shown to the worker | Tool name                                                                                                                              | Add extra context to the result                                                 |
| **Stop**          | When the turn ends, for any outcome                                  | Turn outcome — [complete, awaiting input, or paused](/cowork/loop/agentic-loop#how-a-turn-ends); omit the matcher to fire on all three | Can't block a turn that already ended, but can append context to the transcript |
| **TaskCompleted** | When the task is marked done                                         | —                                                                                                                                      | Observe and log only                                                            |

A hook only reacts to the events and tools it's configured to match — you point it at a tool name (or a pattern covering several) so it only runs where it's relevant, for example only on `bash` and `write_file` calls, or every `web_*` tool.

<Info>
  Every task gets its own isolated [sandbox](/cowork/tasks/execution) automatically, and each hook command runs inside it with a timeout, so a slow or hanging hook can't stall the turn indefinitely.
</Info>

## Configuring hooks

Hooks are defined in a `hooks.json` file, grouped by event. Each entry pairs a matcher (which tool names it applies to) with one or more commands to run:

```json title="hooks.json" theme={null}
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "bash|write_file",
        "hooks": [
          { "type": "command", "command": "python .hooks/check_paths.py", "timeout": 30 }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          { "type": "command", "command": "python .hooks/log_activity.py" }
        ]
      }
    ]
  }
}
```

The `matcher` above (`"bash|write_file"`) limits that hook to two tools; an omitted matcher, like the `Stop` entry, matches everything for that event. Each hook command receives the details of the call — which tool, what arguments, and (for `PostToolUse`) the result — as JSON on standard input, and has to answer within its timeout (30 seconds by default, capped at 60) before the turn moves on.

<Note>
  A worker's hooks are capped to keep them lightweight: up to 8 matchers per event and 4 commands per matcher, with the whole file limited to 16 KB. If `hooks.json` is malformed, it's ignored — with a warning — rather than breaking the task.
</Note>

## What hooks are for

<CardGroup cols={2}>
  <Card title="Validate input" icon="magnifying-glass">
    Run a **PreToolUse** hook to check a tool's arguments before they run — for example, rejecting a shell command that touches a protected path or a file write outside an approved directory.
  </Card>

  <Card title="Auto-format output" icon="wand-magic-sparkles">
    Run a **PostToolUse** hook that reformats or annotates a result — for example, running a linter or formatter after a file edit and feeding the outcome back to the worker.
  </Card>

  <Card title="Enforce guardrails" icon="shield-halved">
    Use **PreToolUse** hooks as a second layer of policy on top of tool approvals — an org-specific rule a worker should never be allowed to break, regardless of what the model decides.
  </Card>

  <Card title="Audit and review" icon="clipboard-check">
    Use **Stop** or **TaskCompleted** hooks to log activity, or to kick off a review pass — for example, notifying an improvement-reviewer once a task settles, feeding [self-improvement](/cowork/autonomy/self-improvement).
  </Card>
</CardGroup>

### How a hook responds

A hook command reports back with an exit code:

* **Success** — the call proceeds normally. The hook can still attach extra context for `PostToolUse`.
* **Block** — for `PreToolUse`, the call is denied and the reason is shown to the worker as the tool's result, so it can adjust course; for `PostToolUse` and `Stop`, the call already happened and the reason is appended as context.
* **Anything else** — treated as a non-blocking warning. The turn continues, and the warning is recorded so you can see it happened.

Blocked calls are never silent — they show up in the task transcript as a failed tool result with the hook's reason, so you can always see why the worker didn't do something.

## Hooks and human-in-the-loop

Hooks and approvals solve different problems, and it helps to keep them separate:

* [Human-in-the-loop approvals](/cowork/collaborate/human-in-the-loop) decide **whether a call is allowed to happen at all** — a person (or the permission classifier) says yes or no before execution.
* **Hooks run after that decision**, once a call has already been approved. A hook can only add a further restriction — it can block a call that was allowed, but it can never approve, skip, or auto-answer an approval on its own.

Think of approvals as the gate, and hooks as a checkpoint just past it: hooks tighten what an already-permitted worker can do, they don't loosen it.

## Next steps

<CardGroup cols={2}>
  <Card title="The agentic loop" icon="arrows-spin" href="/cowork/loop/agentic-loop">
    See where PreToolUse, PostToolUse, and Stop fit in a turn.
  </Card>

  <Card title="Human-in-the-loop" icon="user-check" href="/cowork/collaborate/human-in-the-loop">
    Understand approvals, the permission classifier, and decision memory.
  </Card>

  <Card title="Self-improvement & learning" icon="chart-line" href="/cowork/autonomy/self-improvement">
    Learn how a Stop hook can feed a worker's review-and-learn loop.
  </Card>

  <Card title="Skills" icon="puzzle-piece" href="/cowork/workers/skills">
    See the other worker files that live alongside `hooks.json`.
  </Card>
</CardGroup>
