Skip to main content

Understanding Sync Strategies - Simple Guide

For: SpecWeave Users Version: 0.10.0+ Status: User-Facing Documentation


🎯 IMPORTANT: SpecWeave's Source of Truth

Before we dive into sync strategies, understand this key principle:

✅ CORRECT Architecture:
.specweave/ ←→ GitHub Issues (Local ↔ External)
.specweave/ ←→ Jira Epics (Local ↔ External)
.specweave/ ←→ Azure DevOps Items (Local ↔ External)

❌ WRONG:
GitHub ←→ Jira (External ↔ External - NO!)

Key Points:

  • 📁 .specweave/ is your source of truth (local, permanent, version-controlled)
  • 🪞 External tools are MIRRORS (GitHub, Jira, ADO sync FROM .specweave/)
  • Sync direction: Local ↔ External (NOT External ↔ External)

Why this matters: SpecWeave keeps your specs local and version-controlled. External tools reflect this truth, but they're NOT the source. If you lose access to Jira or GitHub, you still have .specweave/.


What Are Sync Strategies?

When you connect SpecWeave to external tools (Jira, GitHub, Azure DevOps), you need to choose HOW your work is organized in those tools. SpecWeave supports three strategies:

🎯 The Three Strategies (Choose ONE)

1. SIMPLE   ────→  One project/repo, no filtering
2. FILTERED ────→ Multiple projects/repos + boards + filters
3. CUSTOM ────→ Write your own query (power users)

Strategy 1: SIMPLE (Most Common - 70% of Users)

Use when: You have ONE project or repo and want to sync everything

Example Scenarios:

  • ✅ "I have one Jira project called PROJECT-A, sync all issues"
  • ✅ "I have one GitHub repo (myorg/web-app), sync all issues"
  • ✅ "I have one ADO project called Platform, sync all work items"

Configuration (automatically generated by specweave init):

{
"strategy": "simple",
"provider": "jira",
"config": {
"domain": "mycompany.atlassian.net",
"projectKey": "PROJECT-A"
}
}

What gets synced:

  • ✅ ALL issues from PROJECT-A
  • ✅ ALL boards in PROJECT-A
  • ✅ ALL epics, stories, tasks

Pros:

  • ✅ Easiest to set up (2 questions: provider + project)
  • ✅ No configuration complexity
  • ✅ Fast sync (one API call to get everything)

Cons:

  • ❌ Can't filter by boards
  • ❌ Can't sync from multiple projects
  • ❌ All-or-nothing approach

Strategy 2: FILTERED (Advanced - 25% of Users)

Use when: You work across MULTIPLE projects/repos and want board-level control

Example Scenarios:

  • ✅ "I work on 2 Jira projects (PROJECT-A, PROJECT-B), but only want specific boards"
  • ✅ "I manage frontend across 3 repos (web, mobile, shared), need to track all"
  • ✅ "I'm a platform lead across 2 ADO projects with specific area paths"

Configuration (guided by specweave init):

{
"strategy": "filtered",
"provider": "jira",
"config": {
"domain": "mycompany.atlassian.net",
"containers": [
{
"id": "PROJECT-A",
"subOrganizations": ["Team Alpha Board", "Team Beta Board"],
"filters": {
"includeLabels": ["feature", "enhancement"],
"statusCategories": ["To Do", "In Progress"]
}
},
{
"id": "PROJECT-B",
"subOrganizations": ["Platform Board"]
}
]
}
}

What gets synced:

  • ✅ From PROJECT-A: Only "Team Alpha Board" and "Team Beta Board"
  • ✅ From PROJECT-A: Only issues with labels "feature" or "enhancement"
  • ✅ From PROJECT-B: Only "Platform Board"
  • ✅ From both: Only issues with status "To Do" or "In Progress"

Terminology by Provider:

ConceptJiraGitHubAzure DevOps
ContainerProjectRepositoryProject
Sub-OrganizationBoardProject BoardTeam Board
Filter ExampleLabels, ComponentsLabels, MilestonesArea Paths, Work Item Types

Pros:

  • ✅ Maximum flexibility
  • ✅ Work across multiple projects/repos
  • ✅ Board-level control (only sync what you need)
  • ✅ Powerful filtering (labels, assignees, status, etc.)

Cons:

  • ❌ More complex setup (5-10 minutes vs 2 minutes)
  • ❌ Requires understanding of your organization structure
  • ❌ More API calls (can hit rate limits if not careful)

Strategy 3: CUSTOM (Power Users - 5% of Users)

Use when: You need MAXIMUM control with complex queries

Example Scenarios:

  • ✅ "I want all critical bugs from last 3 months across 5 projects"
  • ✅ "I need stories assigned to my team with specific epic links"
  • ✅ "I want work items matching a complex WIQL query"

Configuration:

{
"strategy": "custom",
"provider": "jira",
"config": {
"domain": "mycompany.atlassian.net",
"customQuery": "project IN (PROJECT-A, PROJECT-B, PROJECT-C) AND labels IN (critical, p1) AND sprint IN openSprints() AND assignee IN membersOf('platform-team')"
}
}

Query Syntax by Provider:

  • Jira: JQL (Jira Query Language)
  • GitHub: GitHub search syntax
  • ADO: WIQL (Work Item Query Language)

Pros:

  • ✅ Unlimited power (write ANY query you want)
  • ✅ Complex filtering logic (AND, OR, NOT, IN, etc.)
  • ✅ Access to all provider-specific fields

Cons:

  • ❌ Requires learning query language (JQL/GraphQL/WIQL)
  • ❌ No GUI (must write queries manually)
  • ❌ Error-prone (typos break sync)
  • ❌ Hard to maintain (query becomes stale)

How to Choose?

Decision Tree

┌─────────────────────────────────────────────┐
│ Do you work across multiple projects/repos? │
└────────────────┬────────────────────────────┘

┌────────┴────────┐
NO YES
│ │
▼ ▼
┌─────────┐ ┌────────────────────┐
│ SIMPLE │ │ Do you need board- │
│ │ │ level control? │
└─────────┘ └──────────┬─────────┘

┌────────┴────────┐
NO YES
│ │
▼ ▼
┌─────────┐ ┌──────────────────┐
│ SIMPLE │ │ Do you need │
│(sync all)│ │ complex queries? │
└─────────┘ └────────┬─────────┘

┌────────┴────────┐
NO YES
│ │
▼ ▼
┌──────────┐ ┌────────┐
│ FILTERED │ │ CUSTOM │
└──────────┘ └────────┘

Quick Recommendations

Start with SIMPLE if:

  • ✅ You're new to SpecWeave
  • ✅ Your work lives in one project/repo
  • ✅ You don't need board-level filtering
  • ✅ You want to get started quickly

Upgrade to FILTERED when:

  • ✅ You start working across multiple projects
  • ✅ You only care about specific boards
  • ✅ You want to filter by labels/assignees
  • ✅ Your team grows and spans multiple projects

Use CUSTOM only if:

  • ✅ You're comfortable with JQL/GraphQL/WIQL
  • ✅ You have unique filtering needs not supported by FILTERED
  • ✅ You're okay maintaining query strings

Real-World Examples

Example 1: Simple Strategy (Single Project)

Scenario: Sarah works on a mobile app, one GitHub repo

Setup:

$ specweave init
? Which issue tracker? GitHub
? How is your work organized? Simple (one repo)
? GitHub repo: myorg/mobile-app

✅ Sync profile created: mobile-app-sync

Result: All issues from myorg/mobile-app are synced


Example 2: Filtered Strategy (Cross-Team Work)

Scenario: Mike is a platform lead working across 2 Jira projects, each with multiple boards. He only cares about specific boards.

Setup:

$ specweave init
? Which issue tracker? Jira
? How is your work organized? Filtered (multiple projects + boards)
? Select projects:
☑ PROJECT-PLATFORM
☑ PROJECT-SERVICES
? Select boards from PROJECT-PLATFORM:
☑ Platform Core Board
☑ Infrastructure Board
? Select boards from PROJECT-SERVICES:
☑ API Services Board
? Add filters? Yes
? Include labels: platform, infrastructure, api

✅ Sync profile created: cross-platform-sync

Result: Issues from 3 specific boards with labels "platform", "infrastructure", or "api"


Example 3: Custom Strategy (Power User)

Scenario: Alex needs all P1/P2 bugs from last month across 5 Jira projects

Setup:

$ specweave init
? Which issue tracker? Jira
? How is your work organized? Custom (I'll write my own query)
? Enter JQL query:
project IN (PROJ-A, PROJ-B, PROJ-C, PROJ-D, PROJ-E)
AND priority IN (P1, P2)
AND issuetype = Bug
AND created >= -30d

✅ Sync profile created: critical-bugs-sync

Result: All P1/P2 bugs from last 30 days across 5 projects


Configuration Examples

Jira: Multi-Project with Board Filtering

{
"sync": {
"profiles": {
"cross-team-work": {
"provider": "jira",
"displayName": "Cross-Team Platform Work",
"strategy": "filtered",
"config": {
"domain": "mycompany.atlassian.net",
"containers": [
{
"id": "PLATFORM",
"subOrganizations": ["Core Team Board", "Infrastructure Board"],
"filters": {
"includeLabels": ["platform", "core"],
"assignees": ["platform-lead@company.com"],
"statusCategories": ["To Do", "In Progress"]
}
},
{
"id": "SERVICES",
"subOrganizations": ["API Team Board"],
"filters": {
"includeLabels": ["api", "services"]
}
}
]
},
"timeRange": {
"default": "1M",
"max": "6M"
}
}
}
}
}

GitHub: Multi-Repo Frontend Sync

{
"sync": {
"profiles": {
"frontend-work": {
"provider": "github",
"displayName": "Frontend Across Repos",
"strategy": "filtered",
"config": {
"containers": [
{
"id": "myorg/web-app",
"subOrganizations": ["Frontend Board", "UI Components"],
"filters": {
"includeLabels": ["frontend", "ui"],
"milestones": ["v2.0", "v2.1"]
}
},
{
"id": "myorg/mobile-app",
"subOrganizations": ["Mobile UI Board"],
"filters": {
"includeLabels": ["frontend", "mobile"]
}
}
]
},
"timeRange": {
"default": "1M",
"max": "3M"
}
}
}
}
}

ADO: Multi-Project with Area Paths

{
"sync": {
"profiles": {
"platform-services": {
"provider": "ado",
"displayName": "Platform & Services Teams",
"strategy": "filtered",
"config": {
"organization": "myorg",
"containers": [
{
"id": "Platform",
"filters": {
"areaPaths": ["Platform\\Core", "Platform\\Infrastructure"],
"workItemTypes": ["User Story", "Bug"],
"iterationPaths": ["Sprint 24", "Sprint 25"]
}
},
{
"id": "Services",
"filters": {
"areaPaths": ["Services\\API", "Services\\Integration"],
"workItemTypes": ["Feature", "User Story"]
}
}
]
},
"timeRange": {
"default": "1M",
"max": "6M"
}
}
}
}
}

Migration Guide

From Simple to Filtered

Before (Simple):

{
"strategy": "simple",
"config": {
"domain": "mycompany.atlassian.net",
"projectKey": "PROJECT-A"
}
}

After (Filtered):

{
"strategy": "filtered",
"config": {
"domain": "mycompany.atlassian.net",
"containers": [
{
"id": "PROJECT-A",
"subOrganizations": ["Board 1", "Board 2"]
},
{
"id": "PROJECT-B",
"subOrganizations": ["Board 3"]
}
]
}
}

How to migrate:

  1. Edit .specweave/config.json
  2. Change strategy from "simple" to "filtered"
  3. Replace projectKey with containers array
  4. Add board names to subOrganizations
  5. Test sync: /sw-jira:sync <increment-id>

Troubleshooting

"Strategy not specified" Error

Cause: Your config doesn't have a strategy field

Fix: Add strategy field (defaults to "simple" for backward compatibility)

{
"strategy": "simple", // ← Add this line
"provider": "jira",
...
}

"Containers array is empty" Error

Cause: You chose "filtered" strategy but didn't provide containers

Fix: Either add containers OR switch to "simple" strategy

{
"strategy": "filtered",
"config": {
"containers": [ // ← Must have at least one container
{
"id": "PROJECT-A"
}
]
}
}

"Cannot find board" Error

Cause: Board name doesn't exist in the project

Fix: Check board names in Jira/GitHub/ADO, update config with correct names

# List boards for a Jira project
curl -u email:token https://mycompany.atlassian.net/rest/agile/1.0/board?projectKeyOrId=PROJECT-A

# Update config with correct board names

Summary

StrategyComplexityUse CaseSetup Time
SIMPLE⭐ EasyOne project/repo2 min
FILTERED⭐⭐⭐ ModerateMultiple projects + boards10 min
CUSTOM⭐⭐⭐⭐⭐ AdvancedComplex queries20 min

Recommendation: Start with SIMPLE, upgrade to FILTERED when needed, use CUSTOM only if you must.

Questions? See SpecWeave Sync Documentation


Version: 0.10.0 Last Updated: 2025-11-09 Author: SpecWeave Team