{"slug": "the-forgotten-symlink-why-it-works-is-not-the-same-as-it-is-maintained", "title": "The Forgotten Symlink: Why 'It Works' Is Not the Same as 'It Is Maintained'", "summary": "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.", "body_md": "The best bug in a tooling repo is the one where you discover someone already solved your problem.\n\nThe worst version is realizing nobody remembered.\n\nWhile adding native Cursor agent and skill support to `ai-assistant-dot-files`\n\n, we found that `.cursor/agents`\n\nand `.cursor/skills`\n\nalready existed in the repo as symlinks.\n\nThey pointed to `../shared/agents`\n\nand `../shared/skills`\n\n.\n\nThat was exactly the design we needed.\n\nThey had been committed on 2026-04-09 in commit `d0b54d3`\n\n, with the message \"expanded to work for all platforms.\"\n\nThen they faded out of the system's working memory.\n\nThe framework has one canonical source of truth: `shared/`\n\n.\n\nAgents, skills, rules, contracts, Knowledge Items, the domain dictionary, team topology, and platform\n\nregistry all live there. Platform-specific files are either symlinked or generated from that canonical\n\nlayer.\n\nThat is how one repo can project the same rules into Claude Code, Cursor, Windsurf, GitHub Copilot, Gemini/Antigravity, and OpenAI Codex.\n\nThe repo has a capability tier system because those tools do not all support the same primitives.\n\nClaude Code has full native agent orchestration. Cursor used to be treated mainly as a rules/persona target,\n\nwith generated `.mdc`\n\nfiles. Then Cursor shipped native Agent Skills and subagents:\n\n`.cursor/skills/*/SKILL.md`\n\n`.cursor/agents/*.md`\n\nThat changed the design.\n\nThe right move was not to generate Cursor-specific copies of the agents and skills. The right move was to symlink Cursor directly to `shared/`\n\n, just like Claude Code already did.\n\nAnd then we found out the repo already had those symlinks.\n\nThe symlinks existed.\n\nWhat did not exist was a system that made them visible, verified, and meaningful.\n\nThey 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.\n\nSo the fix was not \"create symlinks.\"\n\nThe fix was:\n\n`docs/ARCHITECTURE.md`\n\n`shared/platform-registry.json`\n\n`install.sh`\n\nto symlink `.cursor/agents`\n\nand `.cursor/skills`\n\n`scripts/check-parity.sh`\n\nso those symlinks cannot silently disappearThat last part matters most.\n\nIf a behavior is important but not checked, it is folklore.\n\nFolklore decays.\n\nWhen people talk about configuration drift, they usually mean duplicated text getting out of sync.\n\nThat is one kind.\n\nThis was another: a correct structural decision existed, but the rest of the system did not know how to protect it.\n\nThe repo already had a parity script because earlier versions had copied instructions into `.cursorrules`\n\n, `copilot-instructions.md`\n\n, and `CLAUDE.md`\n\nindependently. That drift was easy to see once you knew to look for it.\n\nThe forgotten symlink was quieter.\n\nIt did not fail loudly. It just stopped influencing future design.\n\nThere is a tempting maintenance posture that says: if the file exists and the app loads it, we are done.\n\nThis story made the opposite case.\n\nFor cross-tool AI configuration, \"it works\" is not enough. The stronger invariant is:\n\nThat turns a one-off fix into a maintained feature.\n\nThe lesson is not \"use symlinks.\"\n\nSometimes 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`\n\nfiles with inlined content, even though Cursor agents and skills can symlink directly to `shared/`\n\n.\n\nThe lesson is: make the maintenance contract match the platform's actual capabilities.\n\nFor Cursor, the result is now mixed:\n\n`shared/`\n\n`.mdc`\n\nfilesThat mixed strategy is less elegant than pretending everything works the same way.\n\nIt is also truer.\n\nAnd in tooling, true ages better than elegant.\n\n`.cursor/agents`\n\nand `.cursor/skills`\n\nsymlink checks.", "url": "https://wpnews.pro/news/the-forgotten-symlink-why-it-works-is-not-the-same-as-it-is-maintained", "canonical_source": "https://dev.to/orieken/the-forgotten-symlink-why-it-works-is-not-the-same-as-it-is-maintained-17hh", "published_at": "2026-07-08 01:13:08+00:00", "updated_at": "2026-07-08 01:28:27.106095+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "large-language-models", "mlops", "ai-agents"], "entities": ["Cursor", "Claude Code", "Windsurf", "GitHub Copilot", "OpenAI Codex", "Gemini", "Antigravity"], "alternates": {"html": "https://wpnews.pro/news/the-forgotten-symlink-why-it-works-is-not-the-same-as-it-is-maintained", "markdown": "https://wpnews.pro/news/the-forgotten-symlink-why-it-works-is-not-the-same-as-it-is-maintained.md", "text": "https://wpnews.pro/news/the-forgotten-symlink-why-it-works-is-not-the-same-as-it-is-maintained.txt", "jsonld": "https://wpnews.pro/news/the-forgotten-symlink-why-it-works-is-not-the-same-as-it-is-maintained.jsonld"}}