Hook Types
Symphony supports four lifecycle hooks, defined inWORKFLOW.md frontmatter:
after_create
Runs once when a workspace directory is newly created. Fatal if it fails.
before_run
Runs before each agent attempt. Fatal if it fails.
after_run
Runs after each agent attempt completes. Non-fatal.
before_remove
Runs before workspace deletion. Non-fatal.
Configuration
Define hooks in thehooks section of WORKFLOW.md:
WORKFLOW.md
Hook Configuration Fields
Multiline shell script that runs when a workspace is first created. Failure aborts workspace creation.Common uses:
- Clone repository
- Install dependencies
- Generate config files
- Bootstrap database
Multiline shell script that runs before each agent attempt. Failure aborts the current attempt.Common uses:
- Pull latest changes
- Sync dependencies
- Validate environment
- Update configuration
Multiline shell script that runs after each agent attempt. Failure is logged but ignored.Common uses:
- Commit work in progress
- Collect metrics
- Archive logs
- Update dashboards
Multiline shell script that runs before workspace deletion. Failure is logged but ignored.Common uses:
- Archive workspace artifacts
- Clean up external resources
- Notify monitoring systems
- Save debugging snapshots
Timeout in milliseconds for all hooks. Non-positive values fall back to default.Changes apply at runtime to future hook executions.
Execution Environment
Shell Context
Hooks execute in a local shell with these properties:- Shell:
sh -lc <script>(POSIX-compatible, login shell) - Working directory: The workspace path
- Standard streams: Combined stderr/stdout
- Timeout: Configured via
hooks.timeout_ms
Environment Variables
The workspace path and issue context are available implicitly:Implementation Details
From the Elixir implementation (lib/symphony_elixir/workspace.ex):
Use Cases
Repository Setup
Clone and prepare a repository when a workspace is created:Dependency Sync
Keep dependencies updated before each run:Work-in-Progress Commits
Automatically stage changes after each run:Workspace Archival
Save debugging artifacts before cleanup:Database Bootstrap
Set up a test database for each workspace:Conditional Setup
Use shell conditionals for environment-specific setup:Error Handling
Fatal Hooks
after_create and before_run are fatal - failures abort the operation:
Non-Fatal Hooks
after_run and before_remove are non-fatal - failures are logged but execution continues:
Timeout Handling
Hooks that exceedtimeout_ms are killed:
Best Practices
Debugging
View Hook Logs
Hook execution is logged with structured context:Test Hooks Locally
Run hooks manually in a test workspace:Common Issues
Hook times out
Hook times out
- Increase
timeout_msfor slow operations - Optimize the hook (shallow clones, skip optional steps)
- Check for hung processes or network issues
after_create fails repeatedly
after_create fails repeatedly
- Verify network access to clone source
- Check file permissions on workspace root
- Ensure required tools are available (git, npm, etc.)
- Test the hook manually in isolation
Hook output not visible
Hook output not visible
- Hook output is logged with the hook context
- Check log files or console output
- Output is truncated at 2048 bytes in logs