# Hook Lifecycle Roadmap

This page documents the full hook event taxonomy across phase-1 (active) and phase-2 (reserved) and explains how the two sets relate to the Anteroom agent loop.

## Phase split

| Phase | Status | Events |
|-------|--------|--------|
| Phase 1 | **Active** — fully wired into runtime dispatch | `pre_tool`, `post_tool` |
| Phase 2 | **Reserved** — constants declared, runtime wiring coming in a later release (#1494) | `session_start`, `stop`, `approval_requested`, `approval_resolved`, `notification` |

Config validation rejects phase-2 event names with a clear error message so you are not left wondering why a hook is silently ignored.

## Startup snapshot

Phase-1 also emits a `hook.snapshot` audit record for the resolved hook config in effect at startup:

- CLI: once per REPL session
- Web/server: once per process boot

That snapshot is part of the active runtime contract because hook config is session-scoped. See the [Audit Log](../security/audit-log.md) for the payload details.

## Phase-1 events

### `pre_tool`

Fires immediately after the rule-enforcer deny check and before the approval flow.

```
rule-enforcer deny?  →  pre_tool hooks  →  approval flow  →  tool dispatch
```

- A `deny` decision blocks the tool call and surfaces `message` to the user.
- An `ask` decision routes the call through the approval flow with `message` as context.
- An `allow` decision (or no match) continues normally.

### `post_tool`

Fires after the tool completes and its output is available.

```
tool dispatch  →  post_tool hooks  →  agent loop continues
```

- A `deny` decision blocks continuation and surfaces `message` to the user.
- Input rewriting is not supported in phase 1.
- The full tool output is available in the `ANTEROOM_HOOK_OUTPUT` environment variable (command runners) or the `output` field of the JSON payload (webhook runners).

## Phase-2 events (reserved)

These event names are declared as constants in `services/hooks.py` so the codebase is explicit about the full taxonomy.  They are **not dispatched** by the current runtime.

### `session_start`

Intended to fire once when a new session is created, before the first user message is processed.  Useful for audit logging, environment validation, or injecting session context.

### `stop`

Intended to fire when the agent loop exits normally (user `/exit`, end of `--exec` run, or graceful shutdown).  Useful for cleanup, notification, or post-session reporting.

### `approval_requested`

Intended to fire when an approval gate opens (a tool call requires user confirmation).  Allows external systems to be notified before the human decision.

### `approval_resolved`

Intended to fire when an approval gate closes (approved or rejected).  Carries the decision outcome and the original tool call context.

### `notification`

Intended to fire for informational narration events emitted by the agent loop (status updates, plan progress, etc.).  Read-only — no decision is expected.

## Sequencing guide (agent loop)

The diagram below shows where all hook events fit in the full agent loop once phase-2 is wired in.  Phase-2 positions are marked *(reserved)*.

```
session created
  └─ session_start hook  *(reserved)*
       │
       ▼
  user message received
       │
       ▼
  agent loop iteration
    │
    ├─ tool call requested
    │    ├─ rule-enforcer deny check
    │    ├─ pre_tool hooks           ← phase 1, active
    │    ├─ approval_requested hook  *(reserved)*
    │    ├─ approval flow
    │    ├─ approval_resolved hook   *(reserved)*
    │    ├─ tool dispatch
    │    └─ post_tool hooks          ← phase 1, active
    │
    └─ narration event
         └─ notification hook  *(reserved)*
              │
              ▼
  agent loop exit (normal)
    └─ stop hook  *(reserved)*
```

## Config validation errors

If you configure a phase-2 event in your hook config today, validation produces a clear error:

```
[error] hooks.session_start: 'session_start' is a reserved phase-2 lifecycle hook event
and is not yet supported. It will be available in a later release.
Currently supported events: pre_tool, post_tool.
```

Unknown event names that are neither phase-1 nor phase-2 produce a similar error with a note that the name is unrecognised.

## See also

- [Hooks configuration reference](../configuration/config-file.md#hooks)
- [Audit log](../security/audit-log.md) — hook execution is recorded in the audit trail
- GitHub issue [#1271](https://github.com/troylar/anteroom/issues/1271) — phase-1 runtime implementation
- GitHub issue [#1494](https://github.com/troylar/anteroom/issues/1494) — phase-2 lifecycle hook taxonomy
