Skip to content

skills-graph: SkillGraphConnector can record a false-positive Skill Usage from a prompt merely mentioning a SKILL.md path #293

Description

@antejavor

Context

Caught while running scripts/dev-memgraph.sh test-graph-model against a real Claude Code session (map #288/PR #292).

The chain:

  1. claude_code.py's adapter propagates a tool call's own tool_input into that event's metadata (if "tool_input" in payload: metadata["tool_input"] = payload.get("tool_input")).
  2. When the top-level session uses the Task tool to delegate to a subagent, the prompt text itself is that tool call's tool_input — so if the prompt happens to literally mention a real skill's path (e.g. "read the file skills/release/SKILL.md and summarize it"), that string ends up in the parent tool call's own metadata, not just the subagent's.
  3. SkillGraphConnector._on_tool_end calls _extract_skill_file_read(tool_input=None, metadata=event.metadata), which scans metadata for any string that looks like a resolvable SKILL.md path — with no way to distinguish "a path the caller is delegating" from "a path this tool call actually read."
  4. Since the hook subprocess's cwd typically resolves that relative path to a real file, _metadata_from_skill_file reads it for real and records a skill-file-read — at the top level (no agent_name on this event, since it's the parent's own PostToolUse), even though nothing actually read the file at that level; the actual read happened inside the subagent, correctly recorded separately there.

Net effect: a session-level (:Session)-[:USED_SKILL]->(:Skill) edge gets created for a skill nobody read at the session level — just mentioned in a prompt that got delegated onward. This directly contradicts skills-graph's own documented distinction (its CONTEXT.md: "reading arbitrary Markdown or merely mentioning a skill name does not" create Skill Usage).

Worked around for now in test-graph-model's own prompt (making the subagent locate the file itself rather than handing it a literal path), not fixed at the source.

Scope

  • Decide whether _extract_skill_file_read's metadata scan should exclude tool_input/prompt-shaped fields specifically for tool calls whose own tool_name is an agent-spawning one (i.e. don't treat "what the parent asked a subagent to do" as "what the parent itself read").
  • Or: only trust an actual Read-tool (or equivalent) tool call/result for file-path detection, not an arbitrary tool's tool_input/metadata string scan.

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