---
title: "Ticket Sync Enhancements"
status: draft
owner: ng
team: specwright
ticket_project: Gerner-Ventures/gv-exp-specwright
created: 2026-02-26
updated: 2026-02-26
tags: [sync, asana, webhooks, real-time]
---

# Ticket Sync Enhancements

Extend the ticket sync engine with an Asana adapter and real-time reverse sync via webhooks, replacing the cron-based polling approach.

## 1. Background

<!-- specwright:system:1 status:done -->

The ticket sync engine currently supports Jira, Linear, and GitHub Issues via an adapter pattern. Two gaps exist: Asana is not supported (teams using Asana can't use Specwright's ticket sync), and reverse sync (ticket → spec status updates) only runs via a daily cron job, meaning spec statuses can be up to 24 hours behind ticket reality.

**Related:** [#59](https://github.com/Gerner-Ventures/gv-exp-specwright/issues/59), [#56](https://github.com/Gerner-Ventures/gv-exp-specwright/issues/56)

## 2. Asana Ticket Adapter

<!-- specwright:system:2 status:todo -->
<!-- specwright:ticket:github:59 -->

Implement the `TicketAdapter` protocol for Asana, extending ticket sync to teams using Asana for project management.

### 2.1 Implementation

- Use Asana REST API v1 (Personal Access Token or OAuth2 for auth)
- Map spec sections to Asana tasks within a project
- Map spec statuses to Asana custom fields or sections (columns)
- Support Asana webhooks for reverse sync (§3)

### 2.2 Status Mapping

| Spec Status | Asana Equivalent |
|---|---|
| draft | Backlog section |
| todo | To Do section |
| in_progress | In Progress section |
| done | Complete section |
| blocked | Blocked (custom field) |
| deprecated | Archived |

### Acceptance Criteria

- [ ] `AsanaAdapter` implements the `TicketAdapter` protocol
- [ ] Forward sync: spec sections create/update Asana tasks
- [ ] Reverse sync: Asana task status changes update spec status
- [ ] Adapter authenticated via Personal Access Token or OAuth2
- [ ] Status mapping is configurable via `SPECWRIGHT.yaml` ticket mapping
- [ ] Adapter registered in the adapter factory (`from_config()`)
- [ ] Tests cover create, update, and status sync operations

## 3. Real-Time Reverse Sync via Webhooks

<!-- specwright:system:3 status:todo -->
<!-- specwright:ticket:github:56 -->

Replace the cron-based reverse sync with webhook-driven updates for near-real-time spec status tracking.

### 3.1 Webhook Endpoints

| Ticket System | Webhook Endpoint | Events |
|---|---|---|
| GitHub Issues | `/webhooks/github/issues` | `issues.opened`, `issues.closed`, `issues.labeled` |
| Jira | `/webhooks/jira` | `jira:issue_updated` |
| Linear | `/webhooks/linear` | `Issue.update` |
| Asana | `/webhooks/asana` | Task status changes |

### 3.2 Processing

1. Receive webhook event
2. Validate signature/authentication
3. Extract ticket ID and new status
4. Look up linked spec section via ticket link comment
5. Update spec section status via GitHub API (commit to repo)
6. Emit audit event

### 3.3 Reliability

- Idempotent processing (same event processed twice = same result)
- Webhook secret verification for each ticket system
- Dead letter queue for failed processing (log + retry)
- Cron job retained as fallback/catch-up mechanism

### Acceptance Criteria

- [ ] Webhook endpoints for GitHub Issues, Jira, Linear, and Asana
- [ ] Webhook signature/authentication verification for each system
- [ ] Ticket status changes trigger immediate spec status updates
- [ ] Processing is idempotent (duplicate events are safe)
- [ ] Failed webhook processing is logged and retryable
- [ ] Cron job retained as catch-up mechanism (not removed)
- [ ] Latency from ticket change to spec update is under 30 seconds

## 4. Open Questions

- Should webhook endpoints be on the same FastAPI app or a separate service?
- What's the retry policy for failed webhook processing?
- Should Asana OAuth2 support be in scope, or just PAT for v1?
