[FEATURE] Plugin-shipped CLAUDE.md: stable path or @import expansion — the stale-pin failure #82068 predicted, now observed
Preflight Checklist
- [x] I have searched existing requests. This re-files #82068, which the stale bot closed on 2026-09-05 with no maintainer response, and adds the failure that request predicted, now observed.
Problem Statement
#82068 asked for a stable way to point a CLAUDE.md import at a plugin's installed version, and closed with this line:
A static import pinned to .../0.2.4/CLAUDE.md goes silently stale on the next bump, which is worse than what we have.
That happened here, and I can show the whole shape of it.
Our infra team ships shared rules as team/CLAUDE.md inside a private-marketplace plugin. A skill in the same plugin writes the user's memory file as exactly one line:
@/Users/<me>/.claude/plugins/cache/sw-infra/infra-ai-skills/0.10.2/team/CLAUDE.md
The plugin was updated to 0.11.0 on 2026-09-14. Old versions are retained in the cache, so 0.10.1, 0.10.2 and 0.11.0 all sit on disk and the pinned import keeps resolving — to the old copy. From then until 2026-09-17, every session loaded rules from 0.10.2 and skills from 0.11.0 at the same time. Both are visible in a single transcript: the CLAUDE.md contents block cites .../0.10.2/team/CLAUDE.md, and a skill loaded later in that same session announces Base directory for this skill: .../0.11.0/skills/openspec-infra.
The two versions were not equivalent. 0.11.0 added a whole ## Merge Request Description section and flipped MR-description language from English to Russian. On 2026-09-17 the user asked the agent to bring an MR description in line with the team rules; the rule governing MR descriptions was not in the agent's context, because the context held the 0.10.2 file. Nothing in any surface indicated that the loaded rules were a version behind the installed plugin.
Two properties make this silent rather than noisy:
- Retained old versions mean the pin keeps resolving. There is no error, just older content.
- If the old version is ever pruned, an unresolvable import surfaces as nothing. Checked on 2.1.274: a
CLAUDE.mdcontaining@./missing-rules.mdplus a marker line loads the marker, keeps the import line verbatim, and shows no warning that it did not resolve. So the failure mode after a prune is the entire shared rule set disappearing with no signal.
Proposed Solution
Any one of the three from #82068 closes this; they are unchanged and listed cleanest-last:
- A stable
currentsymlink in the plugin cache:~/.claude/plugins/cache/<marketplace>/<plugin>/current/, maintained by the installer, so a static import has something durable to target. - Variable expansion in
@importpaths, e.g.@${CLAUDE_PLUGIN_ROOT:<plugin>@<marketplace>}/CLAUDE.md. - Native plugin memory: let a plugin bundle a
CLAUDE.mdthat loads with memory authority (and reaches subagents) while the plugin is enabled. Plugins already ship skills, commands, agents, hooks and MCP servers; instruction content is the one distribution channel missing.
A cheap partial mitigation, independent of the above: warn when a memory import fails to resolve. Silence there is what turns a pruned cache directory into an invisible loss of every team rule.
Alternative Solutions
Importing from the unversioned marketplace clone works but gives up version pinning, which is the reason for shipping the rules in a plugin at all. Re-running the install skill after every plugin update works only if every engineer remembers, on every bump; that is the failure this report is about.
Use Case Example
An engineering org distributes team conventions to every engineer through a private plugin marketplace, with instruction changes bump-gated and rollbackable alongside the hooks and skills that depend on them.
Additional Context
Claude Code 2.1.270 → 2.1.274, macOS, CLI. Observed 2026-09-14 to 2026-09-17.