Skip to main content

Status Synchronization Guide

Bidirectional status sync between SpecWeave increments and external tools (GitHub, JIRA, Azure DevOps)

Overview

Status synchronization keeps SpecWeave increment statuses in sync with external project management tools. When you complete an increment in SpecWeave, the corresponding GitHub issue, JIRA story, or ADO work item can be automatically updated - and vice versa.

What SpecWeave Syncs (and Doesn't Sync)

✅ Implementation Status (what we sync):

  • Increment status (planning → active → completed → abandoned)
  • Task completion checkboxes (P1, P2, P3 tasks)
  • Content updates (user stories, acceptance criteria, implementation notes)
  • Implementation progress tracking

❌ Scheduling Metadata (what we DON'T sync):

  • Sprint/Iteration assignments - Not synced
  • Story points / effort estimates - Not synced
  • Due dates / target dates - Not synced
  • Release planning dates - Not synced
  • Time tracking (logged/remaining hours) - Not synced
  • Velocity / capacity planning - Not synced

Why This Matters: SpecWeave is implementation-first, not planning-first. We focus on:

  • ✅ What to build (specs, user stories, acceptance criteria)
  • ✅ How to build (plans, architecture, tasks)
  • ✅ Implementation status (completed, in progress, blocked)

We deliberately do NOT manage:

  • ❌ When to build (sprints, iterations, release dates)
  • ❌ How much effort (story points, hours, estimates)
  • ❌ Team capacity (velocity, sprint planning, burndown charts)

Recommendation: Use external tools for scheduling:

  • GitHub Projects - For sprint planning, milestones, roadmaps
  • JIRA Boards - For sprint assignment, story points, velocity tracking
  • Azure DevOps Sprints - For iteration planning, capacity management

See the Scheduling and Planning Guide for recommended workflow.

Supported Tools

  • GitHub Issues - Bidirectional sync with issue statuses
  • JIRA - Bidirectional sync with story/epic statuses
  • Azure DevOps - Bidirectional sync with work item states

Sync Directions

  1. To External (SpecWeave → External): Update GitHub/JIRA/ADO when SpecWeave status changes
  2. From External (External → SpecWeave): Update SpecWeave when GitHub/JIRA/ADO status changes
  3. Bidirectional (Both ways): Sync in both directions with conflict resolution

Quick Start

1. Configure Status Mappings

Edit .specweave/config.json:

{
"sync": {
"statusSync": {
"enabled": true,
"autoSync": false,
"promptUser": true,
"conflictResolution": "prompt",
"mappings": {
"github": {
"planning": "open",
"active": "open",
"completed": "closed",
"abandoned": "closed"
},
"jira": {
"planning": "To Do",
"active": "In Progress",
"completed": "Done",
"abandoned": "Cancelled"
},
"ado": {
"planning": "New",
"active": "Active",
"completed": "Closed",
"abandoned": "Removed"
}
}
}
}
}

When creating increment with GitHub sync:

/sw-github:create-issue 0001-user-authentication

This creates metadata.json with GitHub link:

{
"id": "0001-user-authentication",
"status": "active",
"github": {
"issue": 42,
"url": "https://github.com/owner/repo/issues/42"
}
}

3. Complete Increment

/sw:done 0001

If status sync is enabled, you'll be prompted:

🔄 Status Sync: GitHub Issue #42

SpecWeave status: completed → GitHub status: closed

Update GitHub issue #42 to "closed"?
1. Yes
2. No
3. Custom mapping

Select Yes to sync status to GitHub.


Configuration

Status Mappings

Map SpecWeave statuses to external tool statuses:

{
"sync": {
"statusSync": {
"mappings": {
"github": {
"planning": "open",
"active": "open",
"completed": "closed",
"paused": "open",
"abandoned": "closed"
}
}
}
}
}

SpecWeave Statuses: planning, active, paused, completed, abandoned

GitHub Statuses: open, closed

JIRA Statuses: Depends on your workflow (e.g., To Do, In Progress, Done)

ADO Statuses: New, Active, Resolved, Closed, Removed

Sync Modes

Manual Sync (Default)

Prompts user before syncing:

{
"sync": {
"statusSync": {
"enabled": true,
"autoSync": false,
"promptUser": true
}
}
}

Auto-Sync Mode

Syncs automatically without prompts:

{
"sync": {
"statusSync": {
"enabled": true,
"autoSync": true,
"promptUser": false
}
}
}

Use when: You trust the mappings and want frictionless sync.

Conflict Resolution Strategies

When both SpecWeave and external status change:

{
"sync": {
"statusSync": {
"conflictResolution": "last-write-wins"
}
}
}

Available Strategies

  1. prompt (Recommended): Ask user how to resolve conflict
  2. last-write-wins: Use the most recently changed status
  3. specweave-wins: Always prefer SpecWeave status
  4. external-wins: Always prefer external tool status

Example Conflict:

Conflict detected!

SpecWeave: completed (changed 2025-11-10 12:00)
GitHub: open (changed 2025-11-10 11:00)

How to resolve?
1. Use SpecWeave status (completed → close GitHub issue)
2. Use GitHub status (open → revert SpecWeave to active)

Usage

Sync After Increment Completion

Status sync happens automatically when using /sw:done:

/sw:done 0001-user-authentication

Output:

✅ Increment 0001 completed!

🔄 Status Sync:
✓ GitHub issue #42: open → closed (with comment)
✓ JIRA story PROJ-123: In Progress → Done (with comment)

Manual Sync

Force sync for a specific increment:

/sw-github:sync 0001-user-authentication

Options:

# Specify direction
/sw-github:sync 0001 --direction to-external

# Dry run (preview changes)
/sw-github:sync 0001 --dry-run

Bulk Sync

Sync multiple increments at once:

/sw-github:bulk-sync --time-range 1M

This syncs all increments modified in the last month.


Conflict Resolution

Scenario 1: Last-Write-Wins

Config: conflictResolution: "last-write-wins"

State:

  • SpecWeave: completed (changed at 12:00)
  • GitHub: open (changed at 11:00)

Result: SpecWeave wins (newer timestamp) → GitHub updated to closed

Scenario 2: Prompt User

Config: conflictResolution: "prompt"

State:

  • SpecWeave: completed (changed at 12:00)
  • JIRA: In Progress (changed at 11:30)

Prompt:

Conflict detected!

SpecWeave: completed (2025-11-10 12:00)
JIRA: In Progress (2025-11-10 11:30)

How to resolve?
1. Use SpecWeave status (completed → Done)
2. Use JIRA status (In Progress → active)
3. Cancel sync

User selects Option 1 → JIRA updated to Done

Scenario 3: SpecWeave-Wins

Config: conflictResolution: "specweave-wins"

State:

  • SpecWeave: abandoned
  • ADO: Active

Result: SpecWeave wins → ADO updated to Removed


FAQ

Q: What happens if external tool is down?

A: Sync fails gracefully with error message. Use retry:

/sw-github:sync 0001 --retry

Q: Can I customize status mappings per increment?

A: No, mappings are global in config. But you can use "Custom mapping" option during prompt.

Q: What if I don't want to sync a specific increment?

A: Select "No" when prompted, or don't link external issue in metadata.

Q: How do I see sync history?

A: Check .specweave/logs/sync-events.json:

[
{
"incrementId": "0001-user-authentication",
"tool": "github",
"fromStatus": "active",
"toStatus": "completed",
"timestamp": "2025-11-10T12:00:00Z",
"triggeredBy": "user",
"success": true,
"direction": "to-external"
}
]

Q: Can I sync from external tool to SpecWeave?

A: Yes! The sync is bidirectional by default:

/sw-github:sync 0001

This syncs in both directions:

  • Pulls status/comments/labels FROM GitHub → SpecWeave
  • Pushes task progress/metadata FROM SpecWeave → GitHub

To sync only from GitHub (one-way):

/sw-github:sync 0001 --direction from-github

Q: What if status mapping is invalid?

A: Sync fails with clear error:

❌ Invalid mapping: "completed" → "invalid-status"
Valid GitHub statuses: open, closed

Troubleshooting

Sync not working

Check:

  1. ✅ Status sync enabled: statusSync.enabled: true
  2. ✅ External link exists: metadata.json has github.issue field
  3. ✅ Credentials configured: .env has GITHUB_TOKEN
  4. ✅ Mappings valid: Status names match external tool

Debug:

# Check config
cat .specweave/config.json | jq '.sync.statusSync'

# Check metadata
cat .specweave/increments/0001/metadata.json

# Check sync logs
cat .specweave/logs/sync-events.json | jq '.'

Conflict resolution not triggering

Cause: Both statuses are identical or conflictResolution is not "prompt"

Fix: Change config:

{
"sync": {
"statusSync": {
"conflictResolution": "prompt"
}
}
}

Rate limit errors

Solution: Use bulk sync with delays:

/sw-github:bulk-sync --batch-size 5 --delay 1000

This syncs 5 at a time with 1-second delay between batches.


Best Practices

  1. Use prompt resolution for important projects (manual verification)
  2. Use last-write-wins for fast-paced projects (automatic sync)
  3. Review sync logs regularly (.specweave/logs/sync-events.json)
  4. Test mappings with dry-run before committing
  5. Enable auto-sync only after testing mappings

Next Steps