You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Aegis captures Claude Code lifecycle events (tool use, permission requests, session stops) via HTTP hooks and exposes them through SSE streams, webhooks, and the REST API. This guide covers how hooks work, how to configure them, and how Aegis's hook system differs from alternatives.
3
+
Aegis captures Claude Code lifecycle events via HTTP hooks and enriches them with MCP tool integration, SSE streaming, multi-channel delivery, and enterprise-grade security. This guide covers how hooks work, how to configure them, and how Aegis's architecture compares to alternatives.
4
+
5
+
> **For positioning context**, see the [Competitive Threat Matrix](./competitive-threat-matrix.md).
4
6
5
7
## Overview
6
8
7
-
When Claude Code runs a session, it emits lifecycle events at key points:
9
+
When Claude Code runs a session, it emits lifecycle events at key points. Claude Code supports three native hook types:
10
+
11
+
| Type | Mechanism | Scope |
12
+
|------|-----------|-------|
13
+
|**Command**| Shell script, receives JSON on stdin | Local machine |
14
+
|**HTTP**| POST to a URL with JSON body | Network-accessible |
15
+
|**Prompt**| LLM prompt injection | In-process |
16
+
17
+
Aegis uses **HTTP hooks** exclusively β registering a single endpoint (`POST /v1/hooks/:eventName`) that receives all 29+ CC lifecycle events. This gives Aegis a centralized event bus that no shell-only or config-only approach can match.
18
+
19
+
## Complete Event Reference
20
+
21
+
Aegis handles all Claude Code lifecycle events. Here's the full taxonomy:
22
+
23
+
### Session Lifecycle
24
+
25
+
| Event | Trigger | Aegis Action |
26
+
|-------|---------|-------------|
27
+
|`SessionStart`| Session begins or resumes | Track session state |
28
+
|`SessionEnd`| Session terminates | Clean up resources, emit final metrics |
29
+
|`Setup`|`--init-only` or `--maintenance` mode | One-time CI preparation |
30
+
|`Stop`| Claude finishes responding | Detect waiting-for-input, emit `session.idle`|
31
+
|`StopFailure`| Turn ends due to API error | Circuit breaker protection (see below) |
32
+
33
+
### Tool Lifecycle (Agentic Loop)
8
34
9
35
| Event | Trigger | Aegis Action |
10
36
|-------|---------|-------------|
11
-
|`PreToolUse`| Before a tool executes | Evaluate permission policy, approve or reject |
12
-
|`PostToolUse`| After a tool completes | Record tool usage, emit SSE event |
13
-
|`PostToolUseFailure`| After a tool fails | Log failure, emit error event |
14
-
|`PermissionRequest`| CC asks for user approval | Route to dashboard / Telegram / Slack for human decision |
Aegis registers these hooks automatically when creating a session. You don't need to configure Claude Code hooks manually β Aegis manages the entire lifecycle.
4.**Traced** β OpenTelemetry spans for observability
110
+
### Decision Events
111
+
112
+
Two hook events require a response body that Claude Code acts on:
113
+
114
+
-**`PreToolUse`** β Aegis evaluates the tool against the session's permission profile. Returns `allow`, `deny`, or `ask` (escalate to human).
115
+
-**`PermissionRequest`** β Aegis checks the session's permission mode. Auto-approve modes (`bypassPermissions`, `dontAsk`, `acceptEdits`, `auto`) respond immediately. Others wait for a human decision via dashboard or chat.
116
+
117
+
All other events receive `{ ok: true }` and are processed asynchronously.
After the threshold is reached, Aegis returns `{ ok: true }` to break the retry loop and emits a `circuit_breaker` SSE event. The breaker stays tripped for the session's lifetime. A successful `Stop` event resets it.
151
+
152
+
### Answer Timeout (AskUserQuestion)
153
+
154
+
When Claude Code asks a question via `AskUserQuestion`, Aegis can intercept and answer from external clients:
155
+
156
+
| Variable | Default | Range | Description |
157
+
|---|---|---|---|
158
+
|`ANSWER_TIMEOUT_MS`|`30000`| 1000β600000 | How long to wait for an external answer |
> This section is for technical decision-makers evaluating orchestration tools. For broader competitive context, see the [Competitive Threat Matrix](./competitive-threat-matrix.md).
225
+
226
+
### The Architecture Gap
227
+
228
+
Claude Code hooks are a **point-to-point mechanism**: CC fires an event, one handler responds. Most orchestration tools use this directly β a shell script or HTTP callback that makes a binary allow/deny decision.
229
+
230
+
Aegis layers a **service mesh** on top of that mechanism:
231
+
232
+
```
233
+
Shell-only tools: CC ββhookβββΆ Shell script (allow/deny)
234
+
HTTP-only tools: CC ββhookβββΆ HTTP handler (allow/deny)
235
+
Aegis: CC ββhookβββΆ Hook endpoint βββ¬ββ Permission policy
236
+
βββ OTel tracing
237
+
βββ SSE broadcast
238
+
βββ Multi-channel fan-out
239
+
βββ Audit logging
240
+
βββ Circuit breaker
241
+
βββ Prometheus metrics
242
+
```
243
+
244
+
### Side-by-Side: Permission Control
245
+
246
+
**cc-connect** (Go binary, TOML config):
247
+
248
+
```toml
249
+
# cc-connect config.toml
250
+
[hooks]
251
+
allow_tools = ["Read", "Write", "Bash"]
252
+
deny_tools = ["RMRF"]
253
+
```
254
+
255
+
Flat allow/deny list. No per-session policies. No conditional rules. No audit trail of which tool was approved by which policy.
256
+
257
+
**Native Claude Code** (shell hook):
258
+
259
+
```json
260
+
{
261
+
"hooks": {
262
+
"PreToolUse": [{
263
+
"matcher": "Bash",
264
+
"hooks": [{
265
+
"type": "command",
266
+
"command": "/path/to/block-rm.sh"
267
+
}]
268
+
}]
269
+
}
270
+
}
271
+
```
272
+
273
+
Runs a shell script on every `Bash` tool call. The script must parse JSON from stdin, make a decision, and print JSON to stdout. No built-in audit, no metrics, no fan-out. Each event spawns a new process.
Per-session, per-tool, per-path rules. Decisions are audit-logged with hash chain integrity. Metrics track auto-approvals vs escalations. No shell scripts to maintain.
294
+
295
+
### Side-by-Side: Observability
296
+
297
+
**cc-connect**: Logs to stdout. No structured metrics. No tracing. No real-time event stream.
298
+
299
+
**OpenACP**: Telegram/Discord notifications. No OTel, no Prometheus, no SSE for external consumers.
300
+
301
+
**Aegis**: Every hook event generates:
302
+
- OpenTelemetry span (`tool.invoke` with `sessionId`, `toolName`, `toolUseId`)
**Native CC hooks**: If a Stop hook fails (returns `ok: false`), Claude Code retries forever. The session burns tokens in an infinite loop. No automatic protection.
311
+
312
+
**Aegis**: The circuit breaker detects rapid `StopFailure` events and trips automatically, returning `{ ok: true }` to break the loop. The event is emitted as `circuit_breaker` SSE for monitoring. Configurable threshold and window.
313
+
314
+
```bash
315
+
# Trip after 5 failures in 60 seconds
316
+
HOOK_CIRCUIT_BREAKER_MAX=5
317
+
HOOK_CIRCUIT_BREAKER_WINDOW_MS=60000
318
+
```
319
+
320
+
### Side-by-Side: Multi-Agent Awareness
321
+
322
+
**cc-connect**: Tracks multiple agent backends but has no subagent lifecycle tracking within a session.
323
+
324
+
**Aegis**: `SubagentStart`/`SubagentStop` events track active subagents per session. The dashboard shows live subagent counts. `TaskCreated`/`TaskCompleted` events enable pipeline progress tracking. `TeammateIdle` enables agent team coordination.
0 commit comments