Skip to content

OpenSpec ↔ GitLab Issue Synchronization Pattern

Overview

This document describes the bidirectional synchronization pattern between OpenSpec changes and GitLab issues, enabling consistent tracking across planning artifacts and issue management systems.

Synchronization Approach

Core Principles

  1. Bidirectional Linking: Every OpenSpec change references its GitLab issue, and every GitLab issue references its OpenSpec change
  2. Single Source of Truth: OpenSpec changes contain detailed technical artifacts; GitLab issues provide tracking, assignment, and workflow management
  3. Minimal Duplication: Issue descriptions summarize the change; full details live in OpenSpec artifacts
  4. Consistent Naming: OpenSpec change directory names use kebab-case; issue titles use sentence case

Synchronization Pattern

GitLab Issue #N ←→ openspec/changes/{change-name}/
     │                        │
     │                        ├── proposal.md (includes issue link)
     │                        ├── design.md
     │                        ├── specs/
     │                        └── tasks.md
     └── Description includes: openspec/changes/{change-name}

Implementation Steps

1. OpenSpec Change → GitLab Issue (Create Issue)

When an OpenSpec change exists without a GitLab issue:

# Create issue with structured description
glab issue create \
  --title "Human-Readable Title" \
  --description "## Objective
[Summary from proposal.md ## Why section]

## Changes
[Summary from proposal.md ## What Changes section]

## New Capabilities
[From proposal.md]

## OpenSpec Reference
\`openspec/changes/{change-name}\`

## Acceptance Criteria
- [ ] [Derived from tasks or capabilities]" \
  --label "appropriate-labels"

Key elements: - Title: Human-readable, sentence case - Objective: Why this change matters - Changes: What will be modified - Capabilities: New/modified system capabilities - OpenSpec Reference: Path to change directory - Acceptance Criteria: Checkboxes for tracking

2. GitLab Issue → OpenSpec Change (Create Change)

When a GitLab issue exists without an OpenSpec change:

# Create change directory
mkdir -p openspec/changes/{change-name}

# Create proposal.md with issue link
cat > openspec/changes/{change-name}/proposal.md << 'EOF'
## GitLab Issue

[#{N} - {Issue Title}]({issue-url})

## Why

[Problem statement / motivation from issue]

## What Changes

[Specific changes from issue description]

## Capabilities

### New Capabilities

- `capability-name`: Description

### Modified Capabilities

- `existing-capability`: Changes

## Impact

[Effects on system, users, operations]

## Dependencies

[Other issues/changes required]
EOF

Key elements: - GitLab Issue section at top with link - Why: Problem/motivation - What Changes: Specific modifications - Capabilities: Structured capability changes - Impact: Downstream effects - Dependencies: Related work

3. Add Cross-References

To existing OpenSpec proposal:

# Add GitLab Issue section at top of proposal.md
sed -i '1i## GitLab Issue\n\n[#{N} - {Title}]({url})\n' \
  openspec/changes/{change-name}/proposal.md

To existing GitLab issue:

# Append OpenSpec reference to issue description
glab issue update {N} --description "$(glab issue view {N} --comments=false | sed '1,/^--$/d')

---

## OpenSpec Reference

\`openspec/changes/{change-name}\`"

Naming Conventions

Element Convention Example
OpenSpec directory kebab-case, descriptive migrate-smile-to-tick-tock
GitLab issue title Sentence case, action-oriented "Migrate Smile CDR to Tick-Tock Deployment Pattern"
Capability names kebab-case, noun-focused gitlab-state-backend

Labels Strategy

Apply consistent labels to GitLab issues for filtering:

  • Type: infrastructure, documentation, enhancement, bug
  • Impact: breaking-change, migration, refactoring
  • Domain: monitoring, security, deployment

Verification

Check synchronization status:

# List OpenSpec changes
ls -1 openspec/changes/ | grep -v archive

# List GitLab issues
glab issue list --per-page 50

# Check for missing links
for dir in openspec/changes/*/; do
  if [ -f "$dir/proposal.md" ]; then
    if ! grep -q "GitLab Issue" "$dir/proposal.md"; then
      echo "Missing issue link: $(basename $dir)"
    fi
  fi
done

Workflow Integration

Starting New Work

  1. Create GitLab issue first (for tracking/assignment)
  2. Create OpenSpec change (for technical planning)
  3. Link bidirectionally (using patterns above)
  4. Progress through artifacts (design → specs → tasks)

During Implementation

  • Update GitLab issue status/assignees for workflow tracking
  • Update OpenSpec artifacts for technical details
  • Check acceptance criteria in GitLab issue
  • Reference issue number in commits: git commit -m "feat: implement X (#N)"

Completion

  1. Mark all acceptance criteria complete in GitLab issue
  2. Verify implementation matches OpenSpec artifacts
  3. Archive OpenSpec change: openspec-archive-change
  4. Close GitLab issue

Benefits

  • Traceability: Every change has both planning artifacts and tracking
  • Flexibility: Use GitLab for workflow, OpenSpec for technical depth
  • Discoverability: Find work via issues or change directories
  • Consistency: Standardized structure across all changes
  • Tool Agnostic: Works with any AI assistant or human workflow

Maintenance

Run synchronization periodically:

# Check for orphaned issues (no OpenSpec change)
# Check for orphaned changes (no GitLab issue)
# Create missing elements
# Add cross-references

This can be automated or run on-demand when inconsistencies are detected.