Skip to main content
The schema Observal uses for hook definitions — both the registry hook type (observal registry hook) and hooks wired into harness configs by observal agent pull / observal doctor patch. Claude Code session hooks currently use HOOKS_SPEC_VERSION = "12" in observal_cli/harness_specs/claude_code_hooks_spec.py. Other harnesses have their own hook specs.

Where hooks live

Two distinct things share the name “hook”:
  1. Registry hooks: packaged, versioned hook definitions in the Observal registry. Install them via observal registry hook install.
  2. harness hooks: entries in ~/.claude/settings.json, .kiro/agents/<name>.json, etc. These are written by observal agent pull and observal doctor patch.
Both use the same event vocabulary.

Events

Source: observal_cli/constants.py:VALID_HOOK_EVENTS.

Handler types

Execution modes

Source: observal_cli/constants.py:VALID_HOOK_EXECUTION_MODES.

Scopes

Session delivery hooks

Telemetry is delivered by the session push hook, which reads the local harness transcript and sends session records to /api/v1/ingest/session. It uses the CLI configuration in ~/.observal/config.json; it does not require a curl wrapper, a telemetry environment variable, or an API key header. For Claude Code, observal doctor patch --harness claude-code writes two Observal-managed command hooks into ~/.claude/settings.json: UserPromptSubmit and Stop. Each runs the installed Python interpreter with -m observal_cli.hooks.session_push --harness claude-code. Later patches recognize Observal’s own hooks by their command, so user-authored hooks are left alone. For Kiro, the current IDE/CLI reads .kiro/hooks/observal.json with UserPromptSubmit and Stop triggers. Legacy CLI 2.x (without the IDE) uses inline userPromptSubmit and stop hooks on its agent profile. Both use -m observal_cli.hooks.session_push --harness kiro, not curl. See observal_cli/harness_specs/kiro_hooks_spec.py for the exact formats. Other harnesses have their own capability-specific specs. Use observal doctor to inspect the current installation and observal doctor patch --all-harnesses to instrument detected harnesses.

Event name mapping (Claude Code ↔ Kiro)

Legacy Kiro CLI 2.x inline hooks use camelCase / lowercase event names; current standalone Kiro hooks use PascalCase triggers, like Claude Code. Observal maps the legacy names as follows:

Registry hook payload shape

When submitting a hook to the registry (observal registry hook submit):
Each field is validated server-side against the lists in observal_cli/constants.py (mirrored from observal-server/schemas/constants.py).

Source of truth

  • observal_cli/harness_specs/: per-harness session hook specifications and versions
  • observal_cli/constants.py: valid events, handler types, execution modes, scopes
  • observal-server/schemas/constants.py: server-side mirror
A sync test (tests/test_constants_sync.py) ensures CLI and server stay in lockstep.