[ ] AI Tools 9 min read

$ Building a Claude Code Skill for Codebase Synchronization

Documentation drift is the silent killer of codebases. Your roadmap says one thing, your website another, and your README hasn't been updated in months. Here's how I built a pluggable Claude Code skill that detects drift, shows exactly what's out of sync, and fixes it—with your approval.

Cover image for: Building a Claude Code Skill for Codebase Synchronization
// cover_image.render()

The Problem Everyone Ignores

Every codebase I’ve worked on has the same disease: documentation drift.

It starts innocently. You update your roadmap in GitHub milestones because that’s where the real work happens. The ROADMAP.md file gets updated… eventually. The public roadmap page on your website? Maybe next quarter.

Three months later, your GitHub shows 21 issues in the v1.1.0 milestone with 5% completion. Your ROADMAP.md claims 16 issues with 7% completion. Your website says “Coming Soon” for features you shipped last month.

This isn’t laziness. It’s the natural entropy of information distributed across multiple locations. Every duplicated source of truth is a lie waiting to happen.

I got tired of the manual hunt-and-fix cycle. So I built a Claude Code skill to automate it.


What is Claude Code?

Before diving into the solution, a quick primer for those unfamiliar: Claude Code is Anthropic’s official CLI for Claude. It’s an AI-powered terminal tool that can read your codebase, execute commands, edit files, and—crucially—be extended with custom skills and commands.

Skills are markdown files that define specialized capabilities. When you invoke a skill, Claude Code reads those instructions and gains context about how to perform a particular task. Think of them as domain-specific prompts that turn a general-purpose AI into a specialized tool.

Commands are user-invokable actions that route to skills or perform specific operations.

This architecture creates something powerful: pluggable, versioned, shareable AI workflows that live in your repository alongside your code.


The Architecture: Ground Truth and Drift Detection

The skill I built is called code-parts-syncer. Its core insight is simple but powerful:

Every sync domain needs exactly one source of truth. Everything else derives from it.

For roadmap data, the ground truth is GitHub (milestones and issues). For project instructions, it might be CLAUDE.md. For documentation, perhaps your website or README.

The skill implements a consistent five-step process across all sync domains:

┌─────────────────────────────────────────────────────────────────┐
│                     CODE-PARTS-SYNCER                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   1. FETCH GROUND TRUTH                                         │
│      └── Query authoritative source (e.g., GitHub API)          │
│                                                                 │
│   2. READ CURRENT STATE                                         │
│      └── Extract values from all target files                   │
│                                                                 │
│   3. DETECT DRIFT                                               │
│      └── Compare ground truth with current state                │
│                                                                 │
│   4. REPORT DRIFT                                               │
│      └── Display discrepancies with ✓/✗ indicators              │
│                                                                 │
│   5. APPLY UPDATES (with user confirmation)                     │
│      └── Edit files to align with ground truth                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

This pattern scales to any sync domain: roadmaps, documentation, instructions, configuration—anything that exists in multiple places but should stay consistent.


File Structure: Modular by Design

The skill lives entirely within the .claude/ directory, following Claude Code’s conventions:

.claude/
├── commands/
│   └── caro.sync.md              # Main command dispatcher
└── skills/
    └── code-parts-syncer/
        ├── README.md              # Overview documentation
        ├── roadmap-sync.md        # GitHub ↔ ROADMAP.md ↔ website
        ├── docs-sync.md           # README ↔ website ↔ CLAUDE.md
        └── instructions-sync.md   # CLAUDE.md ↔ CONTRIBUTING ↔ README

Each module is independent. The roadmap syncer knows nothing about documentation sync. This separation makes the system easier to understand, test, and extend.

The total implementation is approximately 1,766 lines of markdown—substantial enough to be thorough, small enough to audit and understand.


The Roadmap Sync Module: A Deep Dive

Let me walk through the fully functional module: roadmap synchronization.

The Sources

This module keeps three sources in sync:

  1. GitHub API (milestones + issues) — The ground truth
  2. ROADMAP.md — Markdown documentation for developers
  3. website/src/pages/roadmap.astro — Public-facing roadmap page

GitHub is authoritative because that’s where work actually happens. Issues get created, closed, moved between milestones. Any process that requires manual duplication will fall behind.

Ground Truth Extraction

The first step queries GitHub using the gh CLI:

# Fetch all milestones with issue counts
gh api repos/owner/repo/milestones --jq '.[] | {
  title,
  description,
  due_on,
  open_issues,
  closed_issues,
  state
}'

# For each milestone, fetch its issues
gh api repos/owner/repo/issues?milestone=1&state=all --jq '.[] | {
  title,
  number,
  state,
  labels: [.labels[].name]
}'

This gives us the real data: actual issue counts, actual completion percentages, actual due dates.

Drift Detection

Next, the skill parses the current state from each target file. For ROADMAP.md, it looks for structured sections:

## v1.1.0 - Core Improvements
- **Status**: 15 open, 1 closed (7% complete)
- **Due**: March 15, 2026 (48 days)

For the Astro website component, it parses the data structures:

const milestones = [
  {
    version: "v1.1.0",
    title: "Core Improvements",
    openIssues: 20,
    closedIssues: 1,
    // ...
  }
];

Then comes the comparison. For each milestone, the skill checks:

  • Issue counts match
  • Completion percentages match
  • Due dates match
  • Issue lists match (if detailed tracking is enabled)

The Drift Report

Here’s what a real drift report looks like:

================================================================================
                        ROADMAP DRIFT DETECTION
================================================================================

Source of Truth: GitHub API (gh api repos/wildcard/caro/milestones)

v1.1.0 - Core Improvements:
  GitHub (TRUTH):    20 open, 1 closed, 21 total (5% complete, 46 days)
  ROADMAP.md:        15 open, 1 closed, 16 total (7% complete, 48 days) ✗ DRIFT
  website/roadmap:   20 open, 1 closed, 21 total (5% complete, 46 days) ✓ SYNCED

v1.2.0 - Extended Platforms:
  GitHub (TRUTH):    8 open, 0 closed, 8 total (0% complete, 90 days)
  ROADMAP.md:        8 open, 0 closed, 8 total (0% complete, 90 days) ✓ SYNCED
  website/roadmap:   8 open, 0 closed, 8 total (0% complete, 90 days) ✓ SYNCED

================================================================================
                              SUMMARY
================================================================================

  ROADMAP.md:        1 milestone needs updates
  website/roadmap:   All synced ✓

  Recommended action: /caro.sync roadmap → Apply updates now

================================================================================

This report tells you exactly what’s wrong without making any changes. The --check flag runs drift detection only—a dry run that shows problems without fixing them.

Safe Updates

When you’re ready to fix the drift, the skill:

  1. Shows a preview of proposed changes
  2. Asks for explicit confirmation
  3. Applies edits using Claude Code’s file editing capabilities
  4. Shows a git diff of all changes

No silent overwrites. No surprises. You see exactly what will change before it happens.


Usage Examples

The command dispatcher makes this ergonomic:

# Show available sync modules
/caro.sync

# Full roadmap sync with updates
/caro.sync roadmap

# Drift detection only (dry run)
/caro.sync --check roadmap

# Check all modules for drift
/caro.sync --check all

The compound all option runs every enabled module, giving you a dashboard view of documentation health across your entire codebase.


Planned Modules: Docs and Instructions

The architecture supports additional sync domains. Two are planned:

Documentation Sync (docs-sync.md)

Keeps installation instructions, feature lists, and CLI examples consistent across:

  • README.md
  • Website documentation pages
  • CLAUDE.md (AI context file)
  • Inline Rust doc comments

The ground truth here is contextual—README for user-facing docs, CLAUDE.md for development context.

Instructions Sync (instructions-sync.md)

Synchronizes project descriptions and development workflows across:

  • CLAUDE.md (primary for development instructions)
  • README.md (user-facing)
  • CONTRIBUTING.md (contributor guidelines)
  • About page on website

Each module follows the same five-step pattern. Adding a new sync domain means writing a new markdown file that defines sources, ground truth, and sync logic.


The Development Workflow

Here’s how I built and shipped this skill—a process that’s itself worth documenting.

Using Worktrees for Isolation

I use a git worktree pattern for feature development:

# Create a dedicated worktree for the feature
git worktree add .worktrees/010-code-parts-syncer -b feature/code-parts-syncer

# Work in isolation
cd .worktrees/010-code-parts-syncer

# All changes happen here, main branch stays clean

Worktrees give you parallel working directories on different branches. I can experiment freely without polluting main or creating WIP commits.

Commit Message Convention

The commit follows Conventional Commits:

feat: Add code-parts-syncer skill for drift detection and sync

Implements a pluggable sync skill to keep related content synchronized
across different parts of the codebase (roadmap, docs, instructions).

**Architecture**:
- Main command dispatcher: /caro.sync
- Pluggable module system for different sync domains
- Ground truth pattern (authoritative source per domain)
- Drift detection before updates
- Safe updates with user confirmation

**Modules**:
- ✓ roadmap-sync.md: Functional - syncs ROADMAP.md ↔ website ↔ GitHub API
- ⋯ docs-sync.md: Placeholder - will sync README ↔ website ↔ CLAUDE.md
- ⋯ instructions-sync.md: Placeholder - will sync CLAUDE.md ↔ README ↔ CONTRIBUTING

Clear, structured, and informative. Anyone reading the git log understands what changed and why.

Ship One Working Module

Notice that only the roadmap module is fully implemented. The others are placeholders with architecture but no logic.

This is intentional. Ship what works, document what’s planned. A single working module proves the pattern. The placeholders show where it’s going without blocking the release.


Key Design Decisions

Why Ground Truth Matters

Without a clear source of truth, sync becomes a nightmare. Which version is correct? If ROADMAP.md says 15 issues and GitHub says 21, which wins?

The ground truth pattern eliminates this ambiguity. GitHub is authoritative for roadmap data—period. Everything else derives from it. No debates, no merge conflicts of intent.

Why Drift Detection Before Updates

The obvious approach is “just sync everything.” But that’s dangerous:

  • You might overwrite intentional variations
  • You lose visibility into what’s changing
  • Automation without understanding leads to accidents

Drift detection first means you always know what’s out of sync. You can review, understand, and approve. The tool informs; you decide.

Why User Confirmation

Claude Code can edit files directly. It would be easy to make sync fully automatic. But that trades safety for convenience—a bad bargain.

The confirmation step keeps humans in the loop. You see the proposed changes, you approve them, they happen. No surprises.

Why Markdown for Skills

Skills are markdown files, not code. This has several advantages:

  • Readable: Anyone can understand what a skill does
  • Auditable: No hidden logic in compiled binaries
  • Versioned: Lives in git with your code
  • Shareable: Copy the file to share the capability
  • Editable: Modify behavior without recompilation

The trade-off is that complex logic requires verbose instructions. But for most workflows, markdown is expressive enough and far more transparent.


Results and Impact

After implementing the roadmap sync:

Before:

  • Manual checking once a month (if I remembered)
  • Drift detected by users pointing out inconsistencies
  • Updates required editing 2-3 files manually
  • 30+ minutes per sync cycle

After:

  • Instant drift detection with /caro.sync --check roadmap
  • Automated updates with single confirmation
  • Git diff visibility for all changes
  • Under 2 minutes for full sync

More importantly, I now know when things are out of sync. The mental overhead of “I should probably check the roadmap files” is gone.


Lessons for Building Your Own Skills

Start With One Module

It’s tempting to design the perfect universal sync system. Don’t. Build one module that solves one problem. Prove the pattern works. Then expand.

The roadmap syncer taught me what the architecture needed. Building it first made the placeholder modules easier to design.

Design for Extension

The pluggable module pattern means adding new sync domains is trivial:

  1. Create a new markdown file in .claude/skills/code-parts-syncer/
  2. Define sources, ground truth, and sync logic
  3. Register it in the command dispatcher

No refactoring. No breaking changes. Just add a file.

Safety Is Non-Negotiable

Any tool that modifies files must be safe by default. Drift detection without modification is the baseline. User confirmation for changes is required. Git diff visibility is essential.

Build trust through transparency, not through hoping nothing goes wrong.

Documentation Is Part of the Skill

The skill includes a README.md that explains the architecture, lists modules, and shows usage examples. When someone invokes /caro.sync without arguments, they get help.

Good tools are self-documenting. The skill should explain itself.


Future Enhancements

Automated Pre-Commit Checks

Imagine a pre-commit hook that runs /caro.sync --check all. If any drift is detected, the commit fails with a helpful message:

❌ Commit blocked: Documentation drift detected

  ROADMAP.md is out of sync with GitHub milestones.
  Run `/caro.sync roadmap` to fix, then commit again.

No more shipping inconsistent documentation.

CI/CD Integration

A GitHub Action that runs drift detection on every PR:

- name: Check Documentation Drift
  run: |
    claude-code /caro.sync --check all --ci
    if [ $? -ne 0 ]; then
      echo "::error::Documentation drift detected. Run /caro.sync locally."
      exit 1
    fi

PRs that introduce drift get flagged automatically.

Health Dashboard

A /caro.sync status --all command that shows sync health across all modules:

================================================================================
                     CODEBASE SYNC HEALTH DASHBOARD
================================================================================

  Module              Status    Last Sync    Issues
  ─────────────────────────────────────────────────
  roadmap-sync        ✓ OK      2 hours ago  0
  docs-sync           ✗ DRIFT   5 days ago   3 files outdated
  instructions-sync   ✓ OK      1 day ago    0

  Overall Health: NEEDS ATTENTION

  Run `/caro.sync docs` to resolve.
================================================================================

Visibility drives action. If you can see the problem, you’ll fix it.


Try It Yourself

If you’re using Claude Code and maintaining documentation across multiple locations, this pattern is immediately applicable.

The key insights are:

  1. Define your ground truth for each sync domain
  2. Detect drift before making any changes
  3. Require confirmation for updates
  4. Show git diffs for transparency
  5. Make it modular for extensibility

You don’t need my specific skill. You need the pattern. Build a sync skill for your own codebase, tailored to your own sources of truth.

Documentation drift is a solved problem—if you have the right tools.


Conclusion: Treat Documentation Like Code

We lint our code. We test our code. We version our code. We review our code before merging.

Why don’t we do the same for documentation?

The answer is usually “it’s too hard” or “there’s no tooling.” Claude Code changes that equation. Skills give you the ability to encode documentation maintenance as automated workflows.

The code-parts-syncer skill is one implementation of a broader idea: documentation as code, with all the rigor that implies. Ground truth sources. Drift detection. Automated sync. Auditable changes.

Your roadmap should never lie. Your README should never be stale. Your website should never contradict your repository.

Build the tools to make it so.


About this post: This essay documents a real skill built for the Caro project—a Rust CLI that converts natural language to shell commands. The code-parts-syncer skill lives in the repository and is actively used to keep roadmap documentation synchronized.

If you’re interested in Claude Code skills, check out the official documentation for getting started. The pattern described here—ground truth, drift detection, safe updates—applies to any synchronization problem you might face.

The best documentation is documentation that maintains itself.

// WAS THIS HELPFUL?