# Cursor Skill Mirror Synchronization in i-have-adhd: How the CI Guardrail Works

> Learn how i-have-adhd ensures Cursor skill integrity with CI Guardrail. Discover the mirror synchronization mechanism and prevent code drift. Click to see how it works.

- Repository: [Ayoub Ghriss/i-have-adhd](https://github.com/ayghri/i-have-adhd)
- Tags: internals
- Published: 2026-08-20

---

**The `i-have-adhd` repository maintains a duplicate copy of its Cursor skill under `.cursor/skills/i-have-adhd/` and enforces strict synchronization through a GitHub Actions workflow that fails CI if the mirror drifts from the canonical definition.**

The repository `ayghri/i-have-adhd` defines its core AI skill in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md). Because Cursor requires skills to reside in a `.cursor` directory but symlinks break on Windows and in GitHub ZIP downloads, the project uses a **file copy with automated enforcement** rather than symbolic links.

## Why Mirror Synchronization Is Necessary

Cursor's runtime expects skills inside `.cursor/skills/`, yet the repository keeps the authoritative definition at the repository root. This creates two constraints:

- **Cross-platform compatibility** — Windows file systems and ZIP archives do not preserve symbolic links, making symlinks unreliable for distribution.
- **Single source of truth** — The canonical [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) must remain the definitive version, with [`.cursor/skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/.cursor/skills/i-have-adhd/SKILL.md) treated as a read-only replica.

The solution is a **byte-identical copy** enforced by continuous integration.

## The CI Enforcement Mechanism

The synchronization guardrail lives in [`.github/workflows/cursor-skill-sync.yml`](https://github.com/ayghri/i-have-adhd/blob/main/.github/workflows/cursor-skill-sync.yml). It triggers on every pull request and every push to `main`:

```bash
cmp skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/SKILL.md \
  || { echo "::error::.cursor copy is out of sync. Run: cp skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/SKILL.md"; exit 1; }

```

This command uses `cmp` to perform a byte-by-byte comparison. If the files differ, the workflow:

1. Prints an actionable error message with the exact copy command needed
2. Exits with status `1`, failing the entire CI pipeline
3. Blocks merge until the mirror is updated

## How to Update the Skill Without Breaking CI

Follow this three-step workflow to modify the skill safely:

```bash

# Step 1: Edit the canonical skill file

nano skills/i-have-adhd/SKILL.md

# Step 2: Copy changes to the mirror location

cp skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/SKILL.md

# Step 3: Commit both files together

git add skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/SKILL.md
git commit -m "Update i-have-adhd skill and sync mirror"

```

Skipping Step 2 produces this CI failure:

```

::error::.cursor copy is out of sync. Run: cp skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/SKILL.md

```

## Key Files in the Synchronization System

| Path | Purpose |
|------|---------|
| [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) | **Canonical definition** — the authoritative skill source |
| [`.cursor/skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/.cursor/skills/i-have-adhd/SKILL.md) | **Mirror copy** — consumed by Cursor's runtime |
| [`.github/workflows/cursor-skill-sync.yml`](https://github.com/ayghri/i-have-adhd/blob/main/.github/workflows/cursor-skill-sync.yml) | **Enforcement layer** — CI check preventing drift |

Both [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md) files must remain identical at all times. The CI workflow treats any divergence as a hard error, ensuring the Cursor environment never executes a stale or inconsistent skill version.

## Summary

- **Cursor skill mirror synchronization** relies on a physical file copy, not symlinks, for Windows and ZIP compatibility
- The `cmp` command in [`.github/workflows/cursor-skill-sync.yml`](https://github.com/ayghri/i-have-adhd/blob/main/.github/workflows/cursor-skill-sync.yml) enforces byte-identical content between [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) and its `.cursor` mirror
- CI fails with a precise remediation command when files diverge, blocking merges until synchronization is restored
- Developers must edit the canonical file first, then copy to the mirror, and commit both changes together

## Frequently Asked Questions

### What happens if I only edit the canonical skill file and forget the mirror?

The GitHub Actions workflow fails with an explicit error message telling you to run `cp skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/SKILL.md`. The pull request cannot merge until you commit the synchronized mirror copy.

### Why not use symlinks instead of a copy?

Symlinks are not portable. Windows file systems handle them inconsistently, and GitHub ZIP downloads flatten symlinks into plain files or broken references. A real copy guarantees the skill works for every clone method.

### Can I edit the `.cursor` mirror directly?

You can, but the next CI run will flag a mismatch if the canonical file differs. The recommended workflow is to treat [`.cursor/skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/.cursor/skills/i-have-adhd/SKILL.md) as read-only and always edit [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) first.

### Does the synchronization check run on every commit?

Yes. The workflow triggers on `pull_request` events and on pushes to the `main` branch, ensuring no divergence slips into the default branch.