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:
| Concept | Jira | GitHub | Azure DevOps |
|---|---|---|---|
| Container | Project | Repository | Project |
| Sub-Organization | Board | Project Board | Team Board |
| Filter Example | Labels, Components | Labels, Milestones | Area 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:
- Edit
.specweave/config.json - Change
strategyfrom"simple"to"filtered" - Replace
projectKeywithcontainersarray - Add board names to
subOrganizations - 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
| Strategy | Complexity | Use Case | Setup Time |
|---|---|---|---|
| SIMPLE | ⭐ Easy | One project/repo | 2 min |
| FILTERED | ⭐⭐⭐ Moderate | Multiple projects + boards | 10 min |
| CUSTOM | ⭐⭐⭐⭐⭐ Advanced | Complex queries | 20 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