Skip to content

install --platform claude: registration block is written through a symlinked ~/.claude/CLAUDE.md, with no opt-out #3805

Description

@royalskynet

graphifyy 0.9.67, macOS arm64, installed via uv tool install graphifyy.

What happened

graphify install --platform claude printed:

  skill installed  ->  ~/.claude/skills/graphify/SKILL.md
  CLAUDE.md        ->  skill registered in ~/.claude/CLAUDE.md

On this machine ~/.claude/CLAUDE.md is a symlink:

$ ls -l ~/.claude/CLAUDE.md
lrwxr-xr-x  ~/.claude/CLAUDE.md -> ~/AGENTS.md

_write_always_on_block opens the path in text mode, so the block was appended to the symlink target — a top-level rules document that is the single source of truth for this setup and is deliberately kept outside ~/.claude. The output named ~/.claude/CLAUDE.md, so nothing in it suggested a file elsewhere had been modified. I only found it by diffing the rules file afterwards.

The docstring around install.py:394 already anticipates symlinked ~/.claude/CLAUDE.md (nix/home-manager, chezmoi, stow) — but only for the case where the write fails. When the symlink is writable, the write silently lands wherever it points.

Repro

mkdir -p /tmp/t/.claude && printf '# my rules\n' > /tmp/t/rules.md
ln -s /tmp/t/rules.md /tmp/t/.claude/CLAUDE.md
HOME=/tmp/t graphify install --platform claude
tail -5 /tmp/t/rules.md   # graphify block is here, not in a file named CLAUDE.md

Asks

  1. Resolve the symlink in the output. skill registered in ~/.claude/CLAUDE.md -> ~/AGENTS.md would have made this a non-event.
  2. An opt-out. claude_md is a hardcoded True in _PLATFORM_CONFIG["claude"] with no CLI flag to skip it, so there is no supported way to install the skill without touching the rules file. A --no-claude-md (or --skill-only) flag would cover both the symlink case and anyone who keeps their rules file under strict change control.
  3. Consider whether the block is still needed for this platform. Claude Code auto-discovers ~/.claude/skills/*/SKILL.md and surfaces the skill by its frontmatter description: — the skill was listed and invocable with the registration block removed. If that holds generally, the always-on block is redundant for --platform claude and could default to off there.

Related: a tuned description: does not survive an upgrade

Adjacent to #3144. The packaged description: is broad ("Use for any question about a codebase, its architecture, file relationships, or project content"), which in practice makes the skill trigger on ordinary code questions where a knowledge graph is not wanted. Narrowing description: fixes that, but every install/upgrade overwrites it — the .bak is announced, which helps, yet the narrowing has to be re-applied by hand each time.

Would you take a patch that preserves an existing frontmatter description: on re-install (or gates it behind --keep-local-description)? Happy to send one.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions