amondnet / amondnet/spec-kit-sdk

feat(sync): Implement UUID-first identification system for cross-platform synchronization

Abierto
#55 0 comentarios 0 reacciones 1 asignado Reclamado por @amondnet Ver en GitHub
good first issue p2 spec type: feature
Lenguaje dominante
TypeScript
Estrellas
6
Forks
1
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

# UUID-First Identification System for Sync Plugin

## Background

Currently, the sync plugin uses `github.issue_number` as the primary identifier for matching specs to remote issues. While `spec_id` (UUID) is generated and stored, it's not actively used for synchronization operations. This creates limitations for cross-platform sync and robust issue tracking.

## Current Implementation Analysis

### How it works now:
- **Primary ID**: `github.issue_number` used for push/pull operations
- **UUID Generation**: `spec_id` generated in `updateFrontmatter()` after push operations
- **Matching Logic**: Adapter checks `issue_number` to determine update vs create
- **Limitation**: Platform-specific IDs prevent cross-platform synchronization

### Code References:
- UUID generation: `plugins/sync/src/core/frontmatter.ts:41`
- Push logic: `plugins/sync/src/adapters/github/github.adapter.ts:33-34`
- Sync engine: `plugins/sync/src/core/sync-engine.ts:58-61`

## Problem Statement

1. **Late UUID Generation**: UUID created after push, not available during sync operations
2. **No Cross-Platform Support**: Cannot sync same spec across GitHub, Jira, Asana
3. **Fragile Matching**: Relies solely on platform-specific issue numbers
4. **Race Conditions**: Multiple processes might generate different UUIDs
5. **Missing UUID Usage**: Generated UUIDs are stored but never used for identification

## Proposed Solution

### UUID Priority System
```
Current: github.issue_number > spec_id
Proposed: spec_id > github.issue_number (with fallback)
```

### Implementation Strategy

#### 1. Early UUID Generation
```typescript
// Generate UUID during spec scanning, not after push
async function scanSpec(path: string): Promise {
const spec = await parseSpec(path)

// Ensure UUID exists before any operations
if (!spec.frontmatter.spec_id) {
spec.frontmatter.spec_id = generateSpecId()
await saveSpec(spec) // Persist immediately
}
return spec
}
```

#### 2. UUID-First Matching Logic
```typescript
async function findMatchingIssue(spec: SpecDocument) {
const uuid = spec.frontmatter.spec_id
const issueNumber = spec.frontmatter.github?.issue_number

// Priority 1: UUID search (if exists)
if (uuid) {
const issueByUuid = await searchIssueByUuid(uuid)
if (issueByUuid) return issueByUuid
}

// Priority 2: Issue number (backward compatibility)
if (issueNumber) {
const issue = await getIssue(issueNumber)
if (issue && uuid) {
const remoteUuid = extractUuidFromIssue(issue)
if (remoteUuid && remoteUuid !== uuid) {
throw new Error('UUID mismatch - conflict detected')
}
}
return issue
}

return null // Create new
}
```

#### 3. UUID Metadata Embedding
Store UUID in issue body as hidden metadata:
```markdown

# Feature Specification: User Authentication
...
```

## Edge Cases and Handling

### 1. UUID Collision
- **Risk**: Two specs with same UUID (extremely unlikely)
- **Solution**: Validate uniqueness during generation, regenerate if collision detected

### 2. Migration Scenarios
- **Existing specs without UUID**: Generate and persist during first scan
- **Existing issues without UUID**: Embed UUID metadata during next push
- **Mixed state**: Handle gracefully with fallback to issue_number

### 3. Cross-Platform Conflicts
- **Problem**: Same UUID in different platforms with different issue numbers
- **Solution**: UUID takes precedence, update platform-specific IDs

### 4. Race Conditions
- **Problem**: Simultaneous UUID generation
- **Solution**: File-based locking during UUID assignment

### 5. Backward Compatibility
- **Requirement**: Existing workflows must continue working
- **Solution**: Gradual migration with fallback to issue_number

## Implementation Roadmap

### Phase 1: Foundation (Week 1)
- [ ] Move UUID generation to `SpecScanner.scanSpec()`
- [ ] Add UUID validation in frontmatter schema
- [ ] Create UUID extraction utilities for issue body
- [ ] Add tests for UUID generation timing

### Phase 2: UUID Matching (Week 2)
- [ ] Implement `searchIssueByUuid()` in GitHubClient
- [ ] Update `GitHubAdapter.push()` to use UUID-first matching
- [ ] Add UUID metadata embedding in issue body
- [ ] Handle UUID conflicts with validation

### Phase 3: Migration Support (Week 3)
- [ ] Create migration command for existing specs
- [ ] Add backward compatibility layer
- [ ] Implement conflict resolution strategies
- [ ] Add comprehensive edge case testing

### Phase 4: Cross-Platform Prep (Week 4)
- [ ] Abstract UUID logic from platform-specific code
- [ ] Update base adapter interface
- [ ] Prepare for Jira/Asana adapter integration
- [ ] Performance optimization and caching

## Acceptance Criteria

### Functional Requirements
- [ ] UUID generated during spec scan, before any sync operations
- [ ] Push operations use UUID for matching when available
- [ ] Issue body contains UUID metadata for identification
- [ ] Backward compatibility maintained for issue_number-based sync
- [ ] Migration command successfully updates existing specs

### Edge Case Handling
- [ ] Handle specs without UUID (generate and persist)
- [ ] Handle issues without UUID metadata (embed during next push)
- [ ] Detect and resolve UUID conflicts
- [ ] Graceful fallback when UUID matching fails
- [ ] Race condition protection during UUID generation

### Testing Requirements
- [ ] Unit tests for UUID generation timing
- [ ] Integration tests for UUID-first matching
- [ ] Edge case tests for all identified scenarios
- [ ] Migration testing with existing data
- [ ] Performance tests for UUID operations

## Migration Strategy

### Automatic Migration
1. **Scan Phase**: Identify specs without UUID
2. **Generation Phase**: Generate UUIDs for missing specs
3. **Persistence Phase**: Save updated frontmatter to disk
4. **Validation Phase**: Verify UUID uniqueness
5. **Remote Sync Phase**: Embed UUIDs in existing issues

### Manual Override
- Provide `--force-uuid-regeneration` flag for conflict resolution
- Support `--uuid-validation` for consistency checking
- Allow `--dry-run` for preview of changes

## Technical Debt Reduction

This change addresses several technical debt items:
- Late UUID generation causing timing issues
- Unused UUID fields cluttering frontmatter
- Platform-specific sync limitations
- Missing cross-platform synchronization capabilities

## Related Issues

- Resolves cross-platform sync limitations
- Enables future Jira/Asana integration
- Improves sync reliability and conflict resolution
- Provides foundation for advanced sync features

## Implementation Notes

- Maintain existing API compatibility
- Use progressive enhancement approach
- Include comprehensive logging for debugging
- Consider performance impact of UUID searches
- Plan for future platform adapter expansion

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.