hooks configuration section allows you to run custom shell scripts at key points in the workspace lifecycle.
Configuration
WORKFLOW.md
Fields
Shell script executed immediately after a new workspace directory is created.Runs only once when the workspace is first created for an issue. On subsequent runs (workspace reuse), this hook does not execute.Execution context:
- Working directory: Workspace path
- Shell:
sh -lc <script>(POSIX-compatible) - Timeout:
hooks.timeout_ms
- Hook failure aborts workspace creation
- The agent run fails and schedules a retry
- Workspace directory may be removed on creation failure
- Clone repository
- Install dependencies
- Set up environment (mise, asdf, etc.)
- Initialize configuration files
Shell script executed before each agent run attempt.Runs every time an agent session starts, including:
- First run
- Retry attempts
- Continuation runs after hitting
max_turns
- Working directory: Workspace path
- Shell:
sh -lc <script> - Timeout:
hooks.timeout_ms
- Hook failure aborts the current run attempt
- The orchestrator schedules a retry with exponential backoff
- Sync latest code from remote (
git pull) - Refresh dependencies
- Update configuration
- Pre-run validation
Shell script executed after each agent run attempt completes.Runs every time an agent session ends, regardless of outcome:
- Success
- Failure
- Timeout
- Cancellation/stall
- Working directory: Workspace path (if it exists)
- Shell:
sh -lc <script> - Timeout:
hooks.timeout_ms
- Hook failure is logged and ignored
- The agent run’s original outcome is preserved
- Cleanup/reconciliation continues normally
- Upload logs/artifacts
- Post-run metrics collection
- Cleanup temporary files
- Send notifications
Shell script executed before a workspace directory is deleted.Runs when:
- Issue transitions to a terminal state (orchestrator cleanup)
- Service startup cleanup for terminal issues
- Manual workspace removal
- Working directory: Workspace path (only if directory exists)
- Shell:
sh -lc <script> - Timeout:
hooks.timeout_ms
- Hook failure is logged and ignored
- Workspace removal proceeds even if hook fails
- Archive workspace state
- Upload final artifacts
- Clean up external resources
- Send completion notifications
Maximum execution time for all hooks in milliseconds (1 minute default).If a hook exceeds this timeout:
- The process is killed (
Task.shutdown(task, :brutal_kill)) - The hook is treated as failed
- Failure handling depends on the hook type (see above)
Execution Context
All hooks execute in a task with:- Shell:
sh -lc(POSIX login shell) - Working directory: Workspace path
- Output: stderr redirected to stdout
- Timeout:
hooks.timeout_ms
Environment Variables
Hooks inherit the environment from the Symphony process, including:HOME,USER,PATH- Any custom variables set before launching Symphony
- Shell profile/rc files are loaded (
-lflag)
Exit Codes
Hook success/failure is determined by exit code:- 0: Success
- Non-zero: Failure (logged with output)
Hook Lifecycle Example
For issueABC-123 across multiple runs:
First Run (New Workspace)
Second Run (Workspace Reuse)
Terminal Cleanup
Hook Output Handling
Hook output is logged for debugging:Common Patterns
Repository Clone and Setup
Python Environment
Tool Version Management (mise/asdf)
Artifact Upload
Conditional Logic
Debugging Hooks
To test hook execution manually:Configuration Reloading
Hook configuration changes are applied dynamically:- New hook scripts take effect immediately
- Timeout changes apply to future hook executions
- Running hooks complete with their original configuration