Webhook Mappings & Event Routing
Active Development
The event routing system is stable. Additional canonical triggers and mapping features may be added as the platform evolves.
Aether uses a three-layer mapping system to route incoming webhooks to the right agents:
Source Event → [Source Event Mapping] → Canonical Trigger
│
[Trigger Task Mapping]
│
Tasks → Agents- Source Event Mapping — Maps platform-specific events to a canonical trigger
- Trigger Task Mapping — Maps the canonical trigger to one or more tasks
- Task Definition — Each task has an assigned agent (or fallback prompt)
The Unified Webhook Endpoint
All webhooks arrive at:
POST /webhook/:slugFor built-in integrations, the slug is the source name: github, gitlab, jira, plane.
Configure your webhooks in GitHub/GitLab/Jira/Plane to point here:
https://your-aether-host/webhook/github
https://your-aether-host/webhook/gitlab
https://your-aether-host/webhook/jira
https://your-aether-host/webhook/planeLayer 1: Source Event Mappings
These define how platform-specific events map to canonical triggers.
Default Mappings
After seeding (POST /api/tasks/sources/seed), these mappings exist:
| Source | Event | Action | Canonical Trigger |
|---|---|---|---|
| github | issues | opened | issue.created |
| github | issues | closed | issue.closed |
| github | pull_request | opened | pr.opened |
| github | pull_request | closed | pr.closed |
| github | issue_comment | created | issue.commented |
| gitlab | Issue Hook | open | issue.created |
| gitlab | Issue Hook | close | issue.closed |
| gitlab | Merge Request Hook | open | pr.opened |
| jira | jira:issue_created | — | issue.created |
| jira | jira:issue_updated | — | issue.updated |
| jira | comment_created | — | issue.commented |
| plane | issue.created | — | issue.created |
| plane | issue.updated | — | issue.updated |
Adding a Custom Mapping
curl -X POST http://localhost:8000/api/tasks/sources \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"event_name": "pull_request",
"action": "ready_for_review",
"canonical_trigger": "pr.ready"
}'When action is null or omitted, the mapping matches any action for that event.
Listing Mappings
curl http://localhost:8000/api/tasks/sourcesLayer 2: Trigger → Task Mappings
These define which tasks fire when a canonical trigger occurs. Multiple tasks can be mapped to one trigger.
Default Mappings
After seeding (POST /api/tasks/triggers/seed):
| Canonical Trigger | Tasks That Fire |
|---|---|
issue.created | PM analysis + TA technical review |
pr.opened | QA review + TA code review |
issue.updated | PM sync |
| And more... |
Adding a Trigger Mapping
curl -X POST http://localhost:8000/api/tasks/triggers \
-H "Content-Type: application/json" \
-d '{
"canonical_trigger": "pr.opened",
"task_id": "security_scan"
}'This adds a third task to fire when any PR is opened — alongside the existing QA and TA tasks.
Listing Trigger Mappings
curl http://localhost:8000/api/tasks/triggersLayer 3: Task Definitions
Tasks define what happens and which agent handles it.
Default Tasks
After seeding (POST /api/tasks/seed):
| Task ID | Assigned Agent | Purpose |
|---|---|---|
triage_initial_intent | pm_sarah | Understand issue intent |
tech_discovery_review | ta_leo | Technical feasibility |
intent_interpretation | pm_sarah | Clarify requirements |
technical_grooming | ta_leo | Prepare for implementation |
dev_environment_setup | hub_system | Dev environment setup |
feature_implementation | dev_alex | Write code |
code_quality_audit | ta_leo | Review code quality |
quality_verification | qa_quinn | Test deployment |
customer_uat_sync | pm_sarah | Customer communication |
Creating a Custom Task
curl -X POST http://localhost:8000/api/tasks \
-H "Content-Type: application/json" \
-d '{
"id": "security_scan",
"name": "Security: Review PR for vulnerabilities",
"description": "Review PR changes for security vulnerabilities",
"actor_id": "ta_leo",
"actor_fallback": "You are a security expert. Review this code change for security vulnerabilities."
}'Seeding Everything at Once
To seed all defaults:
curl -X POST http://localhost:8000/api/agents/seed
curl -X POST http://localhost:8000/api/tasks/seed
curl -X POST http://localhost:8000/api/tasks/triggers/seed
curl -X POST http://localhost:8000/api/tasks/sources/seedAll seed endpoints return {"created": N, "skipped": M} and are safe to run multiple times.
End-to-End Example
Scenario: GitHub PR opened → QA review + TA code review
1. Source event mapping:
source: github
event: pull_request
action: opened
→ canonical_trigger: pr.opened2. Trigger → task mappings:
pr.opened → [qa_review_task, ta_code_review_task]3. Task definitions:
qa_review_task → actor: qa_quinn
ta_code_review_task → actor: ta_leo4. What happens:
- GitHub sends
POST /webhook/githubwith the PR payload - Aether looks up:
(github, pull_request, opened)→pr.opened - Aether looks up:
pr.opened→[qa_review_task, ta_code_review_task] - Aether calls
qa_quinnvia LLM → posts QA review as PR comment - Aether calls
ta_leovia LLM → posts technical analysis as PR comment
Canonical Trigger Reference
Built-in triggers (you can add custom ones):
| Trigger | When It Fires |
|---|---|
issue.created | New issue opened |
issue.updated | Issue edited |
issue.closed | Issue closed |
issue.commented | Comment added to issue |
pr.opened | Pull request opened |
pr.updated | PR modified |
pr.closed | PR closed |
pr.merged | PR merged |
pr.reviewed | Review submitted |
deployment.completed | Deployment finished |
Testing Webhooks
Send test webhooks without configuring the actual external service:
# Simulate a GitHub issue being opened
curl -X POST http://localhost:8000/webhook/github \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: issues" \
-d '{
"action": "opened",
"issue": {
"number": 42,
"title": "Add dark mode support",
"body": "Users have requested a dark mode option. This would improve accessibility."
},
"repository": {
"full_name": "myorg/myrepo"
}
}'
# Check logs to see processing
docker-compose logs -f goway | grep -i webhookIf you see the webhook being received but no agent response:
- Verify
source_event_mappingshas a mapping for(github, issues, opened) - Verify
trigger_task_mappingsmapsissue.createdto at least one task - Verify the task's
actor_idreferences an existing agent
Troubleshooting
Webhook received but nothing happens:
# Check source event mappings
curl http://localhost:8000/api/tasks/sources
# Check trigger mappings
curl http://localhost:8000/api/tasks/triggers
# Check agents exist
curl http://localhost:8000/api/agentsEvents processed but no comment posted:
- Check
TRACKER_UPDATES_ENABLED=truein your env - Verify the tracker token has write permissions
- Check
docker-compose logs -f gowayfor response posting errors
