/fix-duplicates
Automatically detect and resolve duplicate increments with smart conflict resolution
> /plugin marketplace add anton-abyzov/specweave > /plugin install sw@specweave
How it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/fix-duplicates
Context preview
What this command does when you run it.
Automatically detect and resolve duplicate increments with smart conflict resolution
Command definition
fix-duplicates.mddescription: Automatically detect and resolve duplicate increments with smart conflict resolution
disable-model-invocation: true
Fix Duplicate Increments
**Intelligent conflict resolution**: Automatically detects duplicate increments and resolves conflicts by selecting the winner, merging valuable content, and cleaning up losers.
Philosophy
**Data safety first** - This command provides multiple safety layers:
- ✅ Shows resolution plan before making changes
- ✅ Dry-run mode for preview
- ✅ Merges valuable content before deletion
- ✅ Creates detailed resolution reports
- ✅ Requires confirmation unless `--force` flag
Usage
# Detect and fix all duplicates interactively
sw:fix-duplicates
# Preview what would be done (dry-run)
sw:fix-duplicates --dry-run
# Auto-fix with content merging
sw:fix-duplicates --merge
# Force fix without confirmation (use with caution!)
sw:fix-duplicates --force --merge
# Fix specific increment number
sw:fix-duplicates 0031
Options
- `<increment-number>`: Optional. Fix only duplicates of specific increment number (e.g., "31", "0031")
- `--dry-run`: Show what would be done without making changes
- `--merge`: Merge valuable content from losers to winner before deletion
- `--force`: Skip confirmation prompts (for automated scripts)
- `--strategy <name>`: Override default resolution strategy (advanced)
How It Works
Step 1: Detection
Scans `.specweave/increments/` and all special folders:
- Active increments (`.specweave/increments/NNNN-*`)
- Archive (`.specweave/increments/_archive/`)
- Abandoned (`.specweave/increments/_abandoned/`)
- Backlog (`.specweave/increments/_backlog/`)
Detects duplicates by increment number (e.g., all folders starting with `0031-`).
Step 2: Winner Selection
**Automatic prioritization algorithm**:
1. **Status priority** (highest wins):
- active = 5 points
- completed = 4 points
- paused = 3 points
- backlog = 2 points
- abandoned = 1 point
2. **Most recent activity** (tiebreaker):
- Uses `lastActivity` from metadata.json
- Falls back to directory modification time
3. **Completeness** (second tiebreaker):
- More files = more complete
- Larger total size = more complete
4. **Location preference** (final tiebreaker):
- Active folder > Paused > Archive > Abandoned
**Example**:
Increment 0031 exists in 3 locations:
1. active/0031-external-tool-sync (status: active, activity: 2025-11-14) → WINNER
2. archive/0031-external-tool-sync (status: completed, activity: 2025-11-12)
3. abandoned/0031-old-attempt (status: abandoned, activity: 2025-10-01)
Winner: Location 1 (active status + most recent activity)
Step 3: Content Merging (Optional)
When `--merge` flag is enabled:
1. **Merge reports/ folder**:
- Copy all files from losers' `reports/` to winner's `reports/`
- Rename conflicting files: `REPORT.md` → `REPORT-{timestamp}.md`
- Preserves completion summaries, session notes, analysis
2. **Merge metadata.json**:
- Take union of external links (GitHub, JIRA, ADO)
- Preserve all external issue numbers
- Keep winner's primary metadata (status, dates)
3. **Create resolution report**:
- `reports/DUPLICATE-RESOLUTION-{timestamp}.md`
- Documents what was merged from where
- Lists all deleted paths
**Example merge**:
Winner: .specweave/increments/0031-external-tool-sync/
reports/
├─ IMPLEMENTATION-COMPLETE.md (original)
├─ SESSION-NOTES-2025-11-12.md (merged from archive)
└─ DUPLICATE-RESOLUTION-20251115-070000.md (NEW)
Loser 1: .specweave/increments/_archive/0031-external-tool-sync/
reports/
└─ SESSION-NOTES-2025-11-12.md → MERGED to winner
Loser 2: .specweave/increments/_abandoned/0031-old-attempt/
(No valuable content to merge)Step 4: Deletion
**Safety measures**:
- Shows confirmation prompt: `Delete {path}? This will permanently remove {N} files. [y/N]`
- Default answer: `N` (no deletion unless confirmed)
- `--force` flag skips prompts (for CI/automated scripts)
- Dry-run mode never deletes (shows preview only)
Examples
Example 1: Interactive Fix (Recommended)
sw:fix-duplicates
**Output**:
🔍 Scanning for duplicate increments...
Found 2 duplicates:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Duplicate 1: Increment 0031-external-tool-status-sync
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Locations:
1. ✓ (recommended) active/0031-external-tool-status-sync
Status: active | Activity: 2025-11-14 | Files: 12
Reason: Active status + most recent
2. ✗ archive/0031-external-tool-sync
Status: completed | Activity: 2025-11-12 | Files: 10
Resolution Plan:
• Keep: active/0031-external-tool-status-sync
• Delete: archive/0031-external-tool-sync
Delete archive/0031-external-tool-sync? [y/N]: y
✅ Resolved duplicate 0031
• Kept: active/0031-external-tool-status-sync
• Deleted: archive/0031-external-tool-sync (10 files removed)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Duplicates found: 2
Duplicates resolved: 2
Files deleted: 15
Space freed: 2.3 MB
📝 Resolution reports:
• active/0031-external-tool-status-sync/reports/DUPLICATE-RESOLUTION-20251115-070000.mdExample 2: Dry-Run Preview
sw:fix-duplicates --dry-run
**Output**:
🔍 DRY RUN - No files will be deleted
Found 2 duplicates:
Duplicate 1: Increment 0031
[DRY RUN] Would keep: active/0031-external-tool-status-sync
[DRY RUN] Would delete: archive/0031-external-tool-sync (10 files)
Duplicate 2: Increment 0032
[DRY RUN] Would keep: active/0032-increment-number-gap-prevention
[DRY RUN] Would delete: active/0032-prevent-increment-number-gaps (8 files)
Summary:
Would resolve: 2 duplicates
Would delete: 18 files
Would free: 2.5 MB
Run without --dry-run to proceed:
sw:fix-duplicates --merge
Example 3: Auto-Fix with Merge
Read more
description: Automatically detect and resolve duplicate increments with smart conflict resolution disable-model-invocation: true
Fix Duplicate Increments
**Intelligent conflict resolution**: Automatically detects duplicate increments and resolves conflicts by selecting the winner, merging valuable content, and cleaning up losers.
Philosophy
**Data safety first** - This command provides multiple safety layers:
- ✅ Shows resolution plan before making changes
- ✅ Dry-run mode for preview
- ✅ Merges valuable content before deletion
- ✅ Creates detailed resolution reports
- ✅ Requires confirmation unless `--force` flag
Usage
# Detect and fix all duplicates interactively sw:fix-duplicates # Preview what would be done (dry-run) sw:fix-duplicates --dry-run # Auto-fix with content merging sw:fix-duplicates --merge # Force fix without confirmation (use with caution!) sw:fix-duplicates --force --merge # Fix specific increment number sw:fix-duplicates 0031
Options
- `<increment-number>`: Optional. Fix only duplicates of specific increment number (e.g., "31", "0031")
- `--dry-run`: Show what would be done without making changes
- `--merge`: Merge valuable content from losers to winner before deletion
- `--force`: Skip confirmation prompts (for automated scripts)
- `--strategy <name>`: Override default resolution strategy (advanced)
How It Works
Step 1: Detection
Scans `.specweave/increments/` and all special folders:
- Active increments (`.specweave/increments/NNNN-*`)
- Archive (`.specweave/increments/_archive/`)
- Abandoned (`.specweave/increments/_abandoned/`)
- Backlog (`.specweave/increments/_backlog/`)
Detects duplicates by increment number (e.g., all folders starting with `0031-`).
Step 2: Winner Selection
**Automatic prioritization algorithm**:
1. **Status priority** (highest wins):
- active = 5 points
- completed = 4 points
- paused = 3 points
- backlog = 2 points
- abandoned = 1 point
2. **Most recent activity** (tiebreaker):
- Uses `lastActivity` from metadata.json
- Falls back to directory modification time
3. **Completeness** (second tiebreaker):
- More files = more complete
- Larger total size = more complete
4. **Location preference** (final tiebreaker):
- Active folder > Paused > Archive > Abandoned
**Example**:
Increment 0031 exists in 3 locations: 1. active/0031-external-tool-sync (status: active, activity: 2025-11-14) → WINNER 2. archive/0031-external-tool-sync (status: completed, activity: 2025-11-12) 3. abandoned/0031-old-attempt (status: abandoned, activity: 2025-10-01) Winner: Location 1 (active status + most recent activity)
Step 3: Content Merging (Optional)
When `--merge` flag is enabled:
1. **Merge reports/ folder**:
- Copy all files from losers' `reports/` to winner's `reports/`
- Rename conflicting files: `REPORT.md` → `REPORT-{timestamp}.md`
- Preserves completion summaries, session notes, analysis
2. **Merge metadata.json**:
- Take union of external links (GitHub, JIRA, ADO)
- Preserve all external issue numbers
- Keep winner's primary metadata (status, dates)
3. **Create resolution report**:
- `reports/DUPLICATE-RESOLUTION-{timestamp}.md`
- Documents what was merged from where
- Lists all deleted paths
**Example merge**:
Winner: .specweave/increments/0031-external-tool-sync/
reports/
├─ IMPLEMENTATION-COMPLETE.md (original)
├─ SESSION-NOTES-2025-11-12.md (merged from archive)
└─ DUPLICATE-RESOLUTION-20251115-070000.md (NEW)
Loser 1: .specweave/increments/_archive/0031-external-tool-sync/
reports/
└─ SESSION-NOTES-2025-11-12.md → MERGED to winner
Loser 2: .specweave/increments/_abandoned/0031-old-attempt/
(No valuable content to merge)Step 4: Deletion
**Safety measures**:
- Shows confirmation prompt: `Delete {path}? This will permanently remove {N} files. [y/N]`
- Default answer: `N` (no deletion unless confirmed)
- `--force` flag skips prompts (for CI/automated scripts)
- Dry-run mode never deletes (shows preview only)
Examples
Example 1: Interactive Fix (Recommended)
sw:fix-duplicates
**Output**:
🔍 Scanning for duplicate increments...
Found 2 duplicates:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Duplicate 1: Increment 0031-external-tool-status-sync
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Locations:
1. ✓ (recommended) active/0031-external-tool-status-sync
Status: active | Activity: 2025-11-14 | Files: 12
Reason: Active status + most recent
2. ✗ archive/0031-external-tool-sync
Status: completed | Activity: 2025-11-12 | Files: 10
Resolution Plan:
• Keep: active/0031-external-tool-status-sync
• Delete: archive/0031-external-tool-sync
Delete archive/0031-external-tool-sync? [y/N]: y
✅ Resolved duplicate 0031
• Kept: active/0031-external-tool-status-sync
• Deleted: archive/0031-external-tool-sync (10 files removed)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Duplicates found: 2
Duplicates resolved: 2
Files deleted: 15
Space freed: 2.3 MB
📝 Resolution reports:
• active/0031-external-tool-status-sync/reports/DUPLICATE-RESOLUTION-20251115-070000.mdExample 2: Dry-Run Preview
sw:fix-duplicates --dry-run
**Output**:
🔍 DRY RUN - No files will be deleted Found 2 duplicates: Duplicate 1: Increment 0031 [DRY RUN] Would keep: active/0031-external-tool-status-sync [DRY RUN] Would delete: archive/0031-external-tool-sync (10 files) Duplicate 2: Increment 0032 [DRY RUN] Would keep: active/0032-increment-number-gap-prevention [DRY RUN] Would delete: active/0032-prevent-increment-number-gaps (8 files) Summary: Would resolve: 2 duplicates Would delete: 18 files Would free: 2.5 MB Run without --dry-run to proceed: sw:fix-duplicates --merge
Example 3: Auto-Fix with Merge
Spec-first AI development: describe a feature → AI creates spec + plan + tasks, builds autonomously, syncs to GitHub/JIRA. Domain-expert skills for PM, Architect, Frontend, QA learn your patterns permanently. Claude Code, Codex, Cursor, Copilot & more.
Repo: anton-abyzov/specweave
Other commands on specweave.
- /abandon
Abandon an incomplete increment (requirements changed, obsolete)
Open command - /ado-cleanup-duplicates
Clean up duplicate Azure DevOps work items for a Feature. Finds work items with duplicate titles and closes all except the first created item.
Open command - /ado-clone
Clone Azure DevOps repositories to local workspace. Use after init if cloning was skipped, or to add repos later.
Open command - /ado-close
Close Azure DevOps work item when increment complete
Open command - /ado-create
Create Azure DevOps work item from SpecWeave increment
Open command - /ado-import-areas
Import Azure DevOps area paths from a project and map them to SpecWeave projects. Creates 2-level directory structure with area path-based organization.
Open command

