cd /news/developer-tools/the-forgotten-symlink-why-it-works-i… · home topics developer-tools article
[ARTICLE · art-50336] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

The Forgotten Symlink: Why 'It Works' Is Not the Same as 'It Is Maintained'

A developer discovered that symlinks for Cursor agent and skill support already existed in the ai-assistant-dot-files repo but had been forgotten, leading to a maintenance gap. The team fixed this by updating documentation, platform registry, install scripts, and adding parity checks to ensure the symlinks remain visible and verified. The lesson emphasizes that 'it works' is not sufficient for cross-tool AI configuration; the maintenance contract must match platform capabilities.

read3 min views1 publishedJul 8, 2026

The best bug in a tooling repo is the one where you discover someone already solved your problem.

The worst version is realizing nobody remembered.

While adding native Cursor agent and skill support to ai-assistant-dot-files , we found that .cursor/agents

and .cursor/skills

already existed in the repo as symlinks.

They pointed to ../shared/agents

and ../shared/skills

.

That was exactly the design we needed.

They had been committed on 2026-04-09 in commit d0b54d3

, with the message "expanded to work for all platforms."

Then they faded out of the system's working memory.

The framework has one canonical source of truth: shared/

.

Agents, skills, rules, contracts, Knowledge Items, the domain dictionary, team topology, and platform

registry all live there. Platform-specific files are either symlinked or generated from that canonical

layer.

That is how one repo can project the same rules into Claude Code, Cursor, Windsurf, GitHub Copilot, Gemini/Antigravity, and OpenAI Codex.

The repo has a capability tier system because those tools do not all support the same primitives.

Claude Code has full native agent orchestration. Cursor used to be treated mainly as a rules/persona target,

with generated .mdc

files. Then Cursor shipped native Agent Skills and subagents:

.cursor/skills/*/SKILL.md

.cursor/agents/*.md

That changed the design.

The right move was not to generate Cursor-specific copies of the agents and skills. The right move was to symlink Cursor directly to shared/

, just like Claude Code already did.

And then we found out the repo already had those symlinks.

The symlinks existed.

What did not exist was a system that made them visible, verified, and meaningful.

They were created before the capability tier system explained why they mattered. They were not part of the parity check. They were not clearly represented in the platform registry. They were not woven into the install flow as a first-class design choice.

So the fix was not "create symlinks."

The fix was:

docs/ARCHITECTURE.md

shared/platform-registry.json

install.sh

to symlink .cursor/agents

and .cursor/skills

scripts/check-parity.sh

so those symlinks cannot silently disappearThat last part matters most.

If a behavior is important but not checked, it is folklore. Folklore decays.

When people talk about configuration drift, they usually mean duplicated text getting out of sync.

That is one kind.

This was another: a correct structural decision existed, but the rest of the system did not know how to protect it.

The repo already had a parity script because earlier versions had copied instructions into .cursorrules

, copilot-instructions.md

, and CLAUDE.md

independently. That drift was easy to see once you knew to look for it.

The forgotten symlink was quieter.

It did not fail loudly. It just stopped influencing future design.

There is a tempting maintenance posture that says: if the file exists and the app loads it, we are done.

This story made the opposite case.

For cross-tool AI configuration, "it works" is not enough. The stronger invariant is: That turns a one-off fix into a maintained feature.

The lesson is not "use symlinks."

Sometimes copying is right. Sometimes generation is right. Sometimes a platform cannot follow references, so inlining is the only honest option. Cursor rules still need generated .mdc

files with inlined content, even though Cursor agents and skills can symlink directly to shared/

.

The lesson is: make the maintenance contract match the platform's actual capabilities.

For Cursor, the result is now mixed: shared/

.mdc

filesThat mixed strategy is less elegant than pretending everything works the same way.

It is also truer.

And in tooling, true ages better than elegant.

.cursor/agents

and .cursor/skills

symlink checks.

── more in #developer-tools 4 stories · sorted by recency
── more on @cursor 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/the-forgotten-symlin…] indexed:0 read:3min 2026-07-08 ·