Skip to content
AGH RuntimeHooks

Hook Event Catalog

Complete reference for AGH hook events, payload schemas, patch schemas, sync eligibility, and example payloads.

Audience
Operators running durable agent work
Focus
Hooks guidance shaped for scanability, day-two clarity, and operator context.

AGH hooks fire at named runtime points such as session creation, prompt assembly, tool execution, permission decisions, automation runs, and context compaction. Each event has a fixed payload type and a fixed patch type. A hook reads the payload from stdin, decides whether it applies, and writes a JSON patch to stdout.

Runtime Placement

Rendering diagram...

Hook events sit on the runtime path where AGH can either control an operation or observe it.

Reading This Catalog

ColumnMeaning
EventThe exact value used in a hook declaration.
Syncyes means a declaration may set mode = "sync". async only means sync declarations are rejected.
PayloadThe JSON object type delivered to the executor.
PatchThe JSON object type the executor may write to stdout. Empty stdout means an empty patch.
Fires whenThe runtime point that dispatches the event.

Most session-scoped payloads include common session fields:

FieldMeaning
eventCurrent event name.
timestampDispatch timestamp.
session_id, session_name, session_typeSession identity and kind when available.
agent_nameAgent attached to the session or runtime operation.
workspace_id, workspaceWorkspace identity and root path when available.
turn_idCurrent turn when the event is turn-scoped.

Control patches use deny and deny_reason. A deny patch stops the sync hook chain. For pre-operation control points, AGH returns the event-specific denial error to the caller.

Session Events

EventSyncPayloadPatchFires when
session.pre_createyesSessionPreCreatePayloadSessionCreatePatchBefore AGH creates a session record.
session.post_createyesSessionPostCreatePayloadSessionPostCreatePatchAfter AGH creates a session record.
session.pre_resumeyesSessionPreResumePayloadSessionPreResumePatchBefore AGH resumes an existing session.
session.post_resumeyesSessionPostResumePayloadSessionPostResumePatchAfter AGH resumes an existing session.
session.pre_stopyesSessionPreStopPayloadSessionPreStopPatchBefore AGH stops a session.
session.post_stopyesSessionPostStopPayloadSessionPostStopPatchAfter AGH stops a session.

Session lifecycle patches can set session_name, session_type, agent_name, workspace_id, or workspace. Pre-create, pre-resume, and pre-stop hooks can also deny the operation.

Input And Prompt Events

EventSyncPayloadPatchFires when
input.pre_submityesInputPreSubmitPayloadInputPreSubmitPatchBefore a user message is submitted to the agent turn.
prompt.post_assembleyesPromptPayloadPromptPatchAfter AGH assembles the final prompt and before it reaches the agent.

input.pre_submit patches can replace message, append or replace context_blocks, or deny the submission. prompt.post_assemble patches can replace prompt, adjust context_blocks, or deny the assembled prompt.

Event Persistence Events

EventSyncPayloadPatchFires when
event.pre_recordasync onlyEventPreRecordPayloadEventPreRecordPatchBefore an ACP/runtime event is persisted.
event.post_recordasync onlyEventPostRecordPayloadEventPostRecordPatchAfter an ACP/runtime event is persisted.

Event-record hooks are observation hooks. Their payload includes record_type, sequence, and raw content. Their patch type accepts labels, but the current dispatch path does not mutate the stored event record from that patch.

Automation Events

EventSyncPayloadPatchFires when
automation.job.pre_fireyesAutomationJobPreFirePayloadAutomationFirePatchBefore a scheduled or manually triggered job dispatches.
automation.job.post_fireasync onlyAutomationJobPostFirePayloadAutomationObservationPatchAfter a job hands work to a session or run.
automation.trigger.pre_fireyesAutomationTriggerPreFirePayloadAutomationFirePatchBefore a trigger dispatches an automation run.
automation.trigger.post_fireasync onlyAutomationTriggerPostFirePayloadAutomationObservationPatchAfter a trigger hands work to a session or run.
automation.run.completedasync onlyAutomationRunCompletedPayloadAutomationObservationPatchAfter an automation run completes successfully.
automation.run.failedasync onlyAutomationRunFailedPayloadAutomationObservationPatchAfter an automation run fails.

Automation pre-fire patches can replace prompt or set cancel = true. Observation patches are empty structs and are used only to record hook execution.

Autonomy Events

Autonomy hooks cover coordinator bootstrap, task-run leases, and safe child-session spawn. They do not replace the authority of task-run leases or spawn policy. A hook can deny or narrow the exposed pre-operation payload where a control patch exists, but it cannot mint raw claim tokens, complete a task run through channel messages, bypass TTL, widen permissions, or bypass child depth and child count limits.

Coordinator

EventSyncPayloadPatchFires when
coordinator.pre_spawnyesCoordinatorPreSpawnPayloadCoordinatorSpawnPatchBefore AGH creates a managed coordinator session.
coordinator.spawnedyesCoordinatorSpawnedPayloadCoordinatorObservationPatchAfter a managed coordinator session is created.
coordinator.decisionyesCoordinatorDecisionPayloadCoordinatorObservationPatchWhen a coordinator records a semantic coordination decision.
coordinator.stoppedyesCoordinatorStoppedPayloadCoordinatorObservationPatchAfter a managed coordinator session stops.
coordinator.failedyesCoordinatorFailedPayloadCoordinatorObservationPatchAfter coordinator bootstrap or lifecycle handling fails.

CoordinatorSpawnPatch may deny coordinator spawn or replace agent_name, provider, and model. Observation patches are empty and record hook execution only.

Task Run

EventSyncPayloadPatchFires when
task.run.enqueuedyesTaskRunEnqueuedPayloadTaskRunObservationPatchAfter a task run is enqueued and its audit event is committed.
task.run.pre_claimyesTaskRunPreClaimPayloadTaskRunPreClaimPatchBefore a task-run claim transaction commits.
task.run.post_claimyesTaskRunPostClaimPayloadTaskRunObservationPatchAfter a task-run claim and audit event commit.
task.run.lease_extendedyesTaskRunLeaseExtendedPayloadTaskRunObservationPatchAfter a token-fenced heartbeat extends a task-run lease.
task.run.lease_expiredyesTaskRunLeaseExpiredPayloadTaskRunObservationPatchAfter a task-run lease reaches expiry.
task.run.lease_recoveredyesTaskRunLeaseRecoveredPayloadTaskRunObservationPatchAfter lease recovery requeues or finalizes expired work.
task.run.releasedyesTaskRunReleasedPayloadTaskRunObservationPatchAfter a token-fenced task-run lease release.
task.run.completedyesTaskRunCompletedPayloadTaskRunObservationPatchAfter a token-fenced task-run completion.
task.run.failedyesTaskRunFailedPayloadTaskRunObservationPatchAfter a token-fenced task-run failure.

TaskRunPreClaimPatch may deny the claim, add required capabilities, or raise priority_min. It cannot remove task-run requirements or change the selected run after the claim transaction commits. The raw bearer lease token never appears in these hook payloads.

Spawn

EventSyncPayloadPatchFires when
spawn.pre_createyesSpawnPreCreatePayloadSpawnCreatePatchBefore AGH creates a child session from an agent-facing request.
spawn.createdyesSpawnCreatedPayloadSpawnObservationPatchAfter a child session is created.
spawn.parent_stoppedyesSpawnParentStoppedPayloadSpawnObservationPatchWhen parent-stop cleanup reaps a child session.
spawn.ttl_expiredyesSpawnTTLExpiredPayloadSpawnObservationPatchWhen TTL expiry reaps a child session.
spawn.reapedyesSpawnReapedPayloadSpawnObservationPatchAfter child-session reap cleanup completes.

SpawnCreatePatch may deny the spawn or narrow the child request by replacing agent_name, spawn_role, ttl_seconds, or child_permissions. The runtime still rejects permission widening, coordinator-role spawn, cross-workspace spawn, and invalid TTL/depth/child caps.

Agent Process Events

EventSyncPayloadPatchFires when
agent.pre_startyesAgentPreStartPayloadAgentStartPatchBefore AGH starts the ACP agent process.
agent.spawnedyesAgentSpawnedPayloadAgentSpawnedPatchAfter the agent process is spawned.
agent.crashedyesAgentCrashedPayloadAgentCrashedPatchWhen the agent process exits unexpectedly.
agent.stoppedyesAgentStoppedPayloadAgentStoppedPatchAfter the agent process stops.

agent.pre_start patches can replace command, args, or cwd, or deny process startup. The post-start lifecycle patches accept labels for observation.

Turn And Message Events

EventSyncPayloadPatchFires when
turn.startyesTurnStartPayloadTurnStartPatchWhen an agent turn starts.
turn.endyesTurnEndPayloadTurnEndPatchWhen an agent turn ends.
message.startyesMessageStartPayloadMessageStartPatchWhen a streamed message begins.
message.deltaasync onlyMessageDeltaPayloadMessageDeltaPatchFor streaming message deltas.
message.endyesMessageEndPayloadMessageEndPatchWhen a streamed message finishes.

Turn patches can set labels and include the common deny fields. A turn deny stops the hook chain; the current turn events do not return a user-visible denial error. Message patches can replace role, delta_type, or text; only message.start and message.end can run sync hooks.

Tool Events

EventSyncPayloadPatchFires when
tool.pre_callyesToolPreCallPayloadToolCallPatchBefore a tool call executes.
tool.post_callyesToolPostCallPayloadToolResultPatchAfter a tool call succeeds.
tool.post_erroryesToolPostErrorPayloadToolPostErrorPatchAfter a tool call fails.

Tool payloads include tool_call_id, tool_name, tool_namespace, read_only, and tool_input. Pre-call patches can replace the tool name, namespace, read-only flag, or input, and can deny the tool call. Post-call and post-error patches can replace title, tool_result, or error; deny fields on post events stop the hook chain but do not undo an already completed tool result.

Permission Events

EventSyncPayloadPatchFires when
permission.requestyesPermissionRequestPayloadPermissionRequestPatchBefore a permission decision resolves.
permission.resolvedasync onlyPermissionResolvedPayloadPermissionResolvedPatchAfter a permission decision resolves.
permission.deniedasync onlyPermissionDeniedPayloadPermissionDeniedPatchAfter a permission denial resolves.

permission.request patches can set decision, decision_class, and reason, or deny the request. AGH rejects escalation patches that try to turn a blocked, denied, or rejected decision into an allow decision; those hook runs are recorded as rejected.

Context Events

EventSyncPayloadPatchFires when
context.pre_compactyesContextPreCompactPayloadContextPreCompactPatchBefore AGH compacts conversation context.
context.post_compactyesContextPostCompactPayloadContextPostCompactPatchAfter AGH compacts conversation context.

Context compaction payloads include reason, strategy, summary, and context_blocks. Patches can replace reason, strategy, or context_blocks. A pre-compact deny blocks compaction; a post-compact deny only stops the remaining hook chain because compaction has already happened.

Example Payloads And Patches

Deny a risky permission request

permission.request payload:

{
  "event": "permission.request",
  "timestamp": "2026-04-16T15:04:05Z",
  "session_id": "sess_9f4a",
  "agent_name": "coder",
  "workspace_id": "ws_checkout",
  "turn_id": "turn_42",
  "request_id": "perm_123",
  "action": "write",
  "resource": "/Users/you/src/checkout/.env",
  "decision": "ask",
  "decision_class": "write",
  "tool_input": {
    "path": "/Users/you/src/checkout/.env"
  },
  "tool_call": {
    "id": "toolu_123",
    "kind": "edit_file",
    "title": "Edit .env"
  }
}

PermissionRequestPatch denying the operation:

{
  "deny": true,
  "deny_reason": "Secrets files require manual review.",
  "decision": "deny",
  "decision_class": "write",
  "reason": "Protected file pattern matched."
}

Add workspace context to a prompt

prompt.post_assemble payload:

{
  "event": "prompt.post_assemble",
  "timestamp": "2026-04-16T15:04:05Z",
  "session_id": "sess_9f4a",
  "agent_name": "coder",
  "workspace_id": "ws_checkout",
  "workspace": "/Users/you/src/checkout",
  "turn_id": "turn_42",
  "input_class": "user",
  "prompt": "Review the current diff.",
  "context_blocks": [
    {
      "kind": "workspace",
      "text": "Repository: checkout"
    }
  ]
}

PromptPatch replacing the assembled prompt:

{
  "prompt": "[Workspace: checkout]\n\nReview the current diff."
}

Cancel an automation fire

automation.job.pre_fire payload:

{
  "job_id": "job_daily_review",
  "job_name": "weekday-review",
  "agent_name": "reviewer",
  "workspace_id": "ws_checkout",
  "prompt": "Review the repository.",
  "schedule": {
    "mode": "cron",
    "expr": "0 9 * * 1-5"
  },
  "attempt": 1
}

AutomationFirePatch canceling dispatch:

{
  "cancel": true
}

Introspection Surfaces

Use the CLI for local inspection:

agh hooks events --family permission
agh hooks events --sync-only -o json

Use the API when building tooling:

GET /api/hooks/events?family=permission&sync_only=true
GET /api/hooks/catalog?workspace=checkout&event=permission.request
GET /api/hooks/runs?session=sess_9f4a&event=permission.request&last=20

Related references:

On this page