Skip to content

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
  1. Source Event Mapping — Maps platform-specific events to a canonical trigger
  2. Trigger Task Mapping — Maps the canonical trigger to one or more tasks
  3. Task Definition — Each task has an assigned agent (or fallback prompt)

The Unified Webhook Endpoint

All webhooks arrive at:

POST /webhook/:slug

For 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/plane

Layer 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:

SourceEventActionCanonical Trigger
githubissuesopenedissue.created
githubissuesclosedissue.closed
githubpull_requestopenedpr.opened
githubpull_requestclosedpr.closed
githubissue_commentcreatedissue.commented
gitlabIssue Hookopenissue.created
gitlabIssue Hookcloseissue.closed
gitlabMerge Request Hookopenpr.opened
jirajira:issue_createdissue.created
jirajira:issue_updatedissue.updated
jiracomment_createdissue.commented
planeissue.createdissue.created
planeissue.updatedissue.updated

Adding a Custom Mapping

bash
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

bash
curl http://localhost:8000/api/tasks/sources

Layer 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 TriggerTasks That Fire
issue.createdPM analysis + TA technical review
pr.openedQA review + TA code review
issue.updatedPM sync
And more...

Adding a Trigger Mapping

bash
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

bash
curl http://localhost:8000/api/tasks/triggers

Layer 3: Task Definitions

Tasks define what happens and which agent handles it.

Default Tasks

After seeding (POST /api/tasks/seed):

Task IDAssigned AgentPurpose
triage_initial_intentpm_sarahUnderstand issue intent
tech_discovery_reviewta_leoTechnical feasibility
intent_interpretationpm_sarahClarify requirements
technical_groomingta_leoPrepare for implementation
dev_environment_setuphub_systemDev environment setup
feature_implementationdev_alexWrite code
code_quality_auditta_leoReview code quality
quality_verificationqa_quinnTest deployment
customer_uat_syncpm_sarahCustomer communication

Creating a Custom Task

bash
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:

bash
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/seed

All 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.opened

2. 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_leo

4. What happens:

  • GitHub sends POST /webhook/github with 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_quinn via LLM → posts QA review as PR comment
  • Aether calls ta_leo via LLM → posts technical analysis as PR comment

Canonical Trigger Reference

Built-in triggers (you can add custom ones):

TriggerWhen It Fires
issue.createdNew issue opened
issue.updatedIssue edited
issue.closedIssue closed
issue.commentedComment added to issue
pr.openedPull request opened
pr.updatedPR modified
pr.closedPR closed
pr.mergedPR merged
pr.reviewedReview submitted
deployment.completedDeployment finished

Testing Webhooks

Send test webhooks without configuring the actual external service:

bash
# 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 webhook

If you see the webhook being received but no agent response:

  1. Verify source_event_mappings has a mapping for (github, issues, opened)
  2. Verify trigger_task_mappings maps issue.created to at least one task
  3. Verify the task's actor_id references an existing agent

Troubleshooting

Webhook received but nothing happens:

bash
# 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/agents

Events processed but no comment posted:

  1. Check TRACKER_UPDATES_ENABLED=true in your env
  2. Verify the tracker token has write permissions
  3. Check docker-compose logs -f goway for response posting errors

Released under the MIT License.