Hooks

Hooks are shell commands that Syntic Code runs automatically at fixed points in the agent lifecycle. They give you deterministic control over what happens around a session — before and after tools execute, when a session starts, and when Amara decides to stop. Because hooks are ordinary commands, you can use them to enforce guardrails, format code, capture audit logs, or feed additional context to the model.

Lifecycle events

Syntic Code fires hooks at well-defined moments. The PreToolUse event runs before a tool call is executed and can block or allow it. PostToolUse runs immediately after a tool finishes, giving you the result to inspect. SessionStart runs once when a session begins, useful for loading environment context or printing a banner. Stop runs when Amara believes the task is complete, letting you validate the outcome or force the agent to continue. Additional events cover user prompt submission and session teardown so you can bracket the entire interaction.

Configuring hooks

Hooks live in your .syntic/settings.json under a hooks key. Each entry pairs an event with a matcher and one or more commands:

# .syntic/settings.json
{
  "hooks": {
    "PreToolUse": [
      { "matcher": "bash", "command": "syntic-guard --deny-rm" }
    ],
    "PostToolUse": [
      { "matcher": "edit|write", "command": "prettier --write $SYNTIC_FILE" }
    ]
  }
}

Controlling the agent

A hook communicates back to Syntic Code through its exit code and stdout. Exit 0 allows the action to proceed; a non-zero exit on PreToolUse blocks the tool call and returns your stderr to Amara as feedback. On the Stop event, a blocking exit tells the agent the task is not finished. This lets you build enforceable policies — for example, refusing to stop until the test suite passes. See the hooks reference for the full JSON schema passed on stdin.