/sync-status
Detect and fix status desyncs between metadata.json and spec.md
> /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
/sync-status
Context preview
What this command does when you run it.
Detect and fix status desyncs between metadata.json and spec.md
Command definition
sync-status.mddescription: Detect and fix status desyncs between metadata.json and spec.md
disable-model-invocation: true
Sync Status - Desync Detection & Recovery
**CRITICAL**: Detects and fixes status desyncs between metadata.json and spec.md to maintain source-of-truth integrity.
Overview
This command scans increments for status desyncs where metadata.json and spec.md have different status values. This violates CLAUDE.md Rule #7 (source-of-truth discipline) and causes:
- Status line showing wrong increment
- Commands operating on wrong data
- User confusion and broken trust
**Incident Reference**: 2025-11-20 - Silent failure in sw:done caused increment 0047 to have metadata.json="completed" while spec.md="active", breaking status line.
Usage
# Scan all increments for desyncs
sw:sync-status
# Check specific increment
sw:sync-status 0047
# Auto-fix all desyncs (non-interactive)
sw:sync-status --fix
# Scan and show detailed report
sw:sync-status --verbose
Arguments
- `<increment-id>` - Optional. Specific increment to check (e.g., "0047", "0001-test")
- `--fix` - Auto-fix all desyncs without prompting
- `--verbose` - Show detailed report including healthy increments
---
Workflow
Mode 1: Scan All Increments (Default)
**When to use**: Regular maintenance, pre-commit checks, incident investigation
**Steps**:
1. **Scan all increments**:
import { DesyncDetector } from '../../../src/core/increment/desync-detector.js';
const detector = new DesyncDetector();
const report = await detector.scanAll();2. **Display report**:
console.log(detector.formatReport(report));
3. **Example output** (desyncs found):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STATUS DESYNC DETECTION REPORT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Total Scanned: 47 increments
Healthy: 46
Desyncs Found: 1 ⚠️
Errors: 0
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DESYNCS DETECTED (CRITICAL!)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
❌ 0047-us-task-linkage
metadata.json: completed
spec.md: active
Fix command: sw:sync-status --fix
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━4. **If desyncs found, prompt user**:
if (report.totalDesyncs > 0) {
const shouldFix = await promptUser(
`Found ${report.totalDesyncs} desync(s). Fix them? (y/n): `
);
if (shouldFix) {
// Fix all desyncs
for (const desync of report.desyncs) {
const fixed = await detector.fixDesync(desync.incrementId);
if (fixed) {
console.log(`✅ Fixed ${desync.incrementId}`);
} else {
console.error(`❌ Failed to fix ${desync.incrementId}`);
}
}
console.log('');
console.log('All desyncs fixed! Run sw:sync-status to verify.');
}
}5. **Example output** (no desyncs):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STATUS DESYNC DETECTION REPORT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Total Scanned: 47 increments
Healthy: 47
Desyncs Found: 0 ⚠️
Errors: 0
✅ All increments healthy - no desyncs detected!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Mode 2: Check Specific Increment
**When to use**: Investigating specific increment, post-fix verification
**Steps**:
1. **Check increment**:
const detector = new DesyncDetector();
const result = await detector.checkIncrement(incrementId);
2. **Display result**:
if (result.error) {
console.error(`❌ Error checking ${incrementId}: ${result.error}`);
process.exit(1);
}
if (result.hasDesync) {
console.log('━'.repeat(80));
console.log(`❌ DESYNC DETECTED: ${incrementId}`);
console.log('━'.repeat(80));
console.log('');
console.log(`metadata.json: ${result.metadataStatus}`);
console.log(`spec.md: ${result.specStatus}`);
console.log('');
console.log('This violates source-of-truth discipline (CLAUDE.md Rule #7)');
console.log('');
console.log(`Fix: sw:sync-status ${incrementId} --fix`);
console.log('━'.repeat(80));
} else {
console.log(`✅ ${incrementId} - No desync detected`);
console.log(` Status: ${result.metadataStatus}`);
}3. **Example output** (desync found):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
❌ DESYNC DETECTED: 0047-us-task-linkage
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
metadata.json: completed
spec.md: active
This violates source-of-truth discipline (CLAUDE.md Rule #7)
Fix: sw:sync-status 0047 --fix
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Mode 3: Auto-Fix (Non-Interactive)
**When to use**: CI/CD pipelines, automated recovery, pre-commit hooks
**Steps**:
1. **Scan and fix**:
const detector = new DesyncDetector();
const report = await detector.scanAll();
if (report.totalDesyncs > 0) {
console.log(`Found ${report.totalDesyncs} desync(s) - fixing...`);
console.log('');
for (const desync of report.desyncs) {
const fixed = await detector.fixDesync(desync.incrementId);
if (fixed) {
console.log(`✅ Fixed ${desync.incrementId}: ${desync.specStatus} → ${desync.metadataStatus}`);
} else {
console.error(`❌ Failed to fix ${desync.incrementId}`);
}
}
console.log('');
console.log('✅ All desyncs fixed!');
} else {
console.log('✅ No desyncs found - all healthy');
}2. **Example o
Read more
description: Detect and fix status desyncs between metadata.json and spec.md disable-model-invocation: true
Sync Status - Desync Detection & Recovery
**CRITICAL**: Detects and fixes status desyncs between metadata.json and spec.md to maintain source-of-truth integrity.
Overview
This command scans increments for status desyncs where metadata.json and spec.md have different status values. This violates CLAUDE.md Rule #7 (source-of-truth discipline) and causes:
- Status line showing wrong increment
- Commands operating on wrong data
- User confusion and broken trust
**Incident Reference**: 2025-11-20 - Silent failure in sw:done caused increment 0047 to have metadata.json="completed" while spec.md="active", breaking status line.
Usage
# Scan all increments for desyncs sw:sync-status # Check specific increment sw:sync-status 0047 # Auto-fix all desyncs (non-interactive) sw:sync-status --fix # Scan and show detailed report sw:sync-status --verbose
Arguments
- `<increment-id>` - Optional. Specific increment to check (e.g., "0047", "0001-test")
- `--fix` - Auto-fix all desyncs without prompting
- `--verbose` - Show detailed report including healthy increments
---
Workflow
Mode 1: Scan All Increments (Default)
**When to use**: Regular maintenance, pre-commit checks, incident investigation
**Steps**:
1. **Scan all increments**:
import { DesyncDetector } from '../../../src/core/increment/desync-detector.js';
const detector = new DesyncDetector();
const report = await detector.scanAll();2. **Display report**:
console.log(detector.formatReport(report));
3. **Example output** (desyncs found):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STATUS DESYNC DETECTION REPORT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Total Scanned: 47 increments
Healthy: 46
Desyncs Found: 1 ⚠️
Errors: 0
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DESYNCS DETECTED (CRITICAL!)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
❌ 0047-us-task-linkage
metadata.json: completed
spec.md: active
Fix command: sw:sync-status --fix
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━4. **If desyncs found, prompt user**:
if (report.totalDesyncs > 0) {
const shouldFix = await promptUser(
`Found ${report.totalDesyncs} desync(s). Fix them? (y/n): `
);
if (shouldFix) {
// Fix all desyncs
for (const desync of report.desyncs) {
const fixed = await detector.fixDesync(desync.incrementId);
if (fixed) {
console.log(`✅ Fixed ${desync.incrementId}`);
} else {
console.error(`❌ Failed to fix ${desync.incrementId}`);
}
}
console.log('');
console.log('All desyncs fixed! Run sw:sync-status to verify.');
}
}5. **Example output** (no desyncs):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ STATUS DESYNC DETECTION REPORT ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Total Scanned: 47 increments Healthy: 47 Desyncs Found: 0 ⚠️ Errors: 0 ✅ All increments healthy - no desyncs detected! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Mode 2: Check Specific Increment
**When to use**: Investigating specific increment, post-fix verification
**Steps**:
1. **Check increment**:
const detector = new DesyncDetector(); const result = await detector.checkIncrement(incrementId);
2. **Display result**:
if (result.error) {
console.error(`❌ Error checking ${incrementId}: ${result.error}`);
process.exit(1);
}
if (result.hasDesync) {
console.log('━'.repeat(80));
console.log(`❌ DESYNC DETECTED: ${incrementId}`);
console.log('━'.repeat(80));
console.log('');
console.log(`metadata.json: ${result.metadataStatus}`);
console.log(`spec.md: ${result.specStatus}`);
console.log('');
console.log('This violates source-of-truth discipline (CLAUDE.md Rule #7)');
console.log('');
console.log(`Fix: sw:sync-status ${incrementId} --fix`);
console.log('━'.repeat(80));
} else {
console.log(`✅ ${incrementId} - No desync detected`);
console.log(` Status: ${result.metadataStatus}`);
}3. **Example output** (desync found):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ❌ DESYNC DETECTED: 0047-us-task-linkage ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ metadata.json: completed spec.md: active This violates source-of-truth discipline (CLAUDE.md Rule #7) Fix: sw:sync-status 0047 --fix ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Mode 3: Auto-Fix (Non-Interactive)
**When to use**: CI/CD pipelines, automated recovery, pre-commit hooks
**Steps**:
1. **Scan and fix**:
const detector = new DesyncDetector();
const report = await detector.scanAll();
if (report.totalDesyncs > 0) {
console.log(`Found ${report.totalDesyncs} desync(s) - fixing...`);
console.log('');
for (const desync of report.desyncs) {
const fixed = await detector.fixDesync(desync.incrementId);
if (fixed) {
console.log(`✅ Fixed ${desync.incrementId}: ${desync.specStatus} → ${desync.metadataStatus}`);
} else {
console.error(`❌ Failed to fix ${desync.incrementId}`);
}
}
console.log('');
console.log('✅ All desyncs fixed!');
} else {
console.log('✅ No desyncs found - all healthy');
}2. **Example o
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

