Files
reliquary/docs/workpad/reports/2026-05-11-17-skill-activation-mechanics.md
T
g4borg 1b5a7638d7 🧠 Add brain-dump docs for skill adaptation
Add exploratory and design docs for porting dirigent skills to
reliquary, including:
- Explore port options for the gitea skill (in-plugin vs vendored)
- Document activation mechanics across Claude Code and cross-tools
- Include an orchestration comparison between dirigent and reliquary
  approaches
- Add research on glob negation and flag-file activation patterns
- Create uv-detection goals and skill-engines cross-tool reports
- Provide a research plan for future porting work and risk notes
2026-05-11 23:01:30 +02:00

8.7 KiB

Skill activation mechanics in Claude Code

Date: 2026-05-11 Scope: How Claude Code decides when to activate a plugin skill, with focus on file-presence / glob triggers and negation.

Bottom line for the flag-file design

The user's design — sibling skills selected by which flag-files are present, with one skill keyed on "pyproject.toml AND NOT (Justfile|Makefile|mise.toml)" — is partially supported, with no native negation.

  • File-glob activation IS a documented feature: SKILL.md frontmatter accepts a paths: field (glob patterns) that limits when Claude auto-loads the skill. So "activate only when pyproject.toml is present in the working file set" is expressible.
  • Glob negation (!Justfile, !**/Makefile) is not documented and not known to work. The paths: syntax is the same as .claude/rules/ path-specific rules, which document positive patterns and brace expansion only — no exclude/negate operator.
  • Activation is path-driven, not literally "file-exists-in-repo" driven: paths triggers when Claude is working with (reading/writing) a matching file in this turn, not at session start based on repo contents. This is an important distinction for the flag-file model.
  • There is no priority / specificity / tie-break field. Ordering is left to the model.

Workarounds for the "bare pyproject" case:

  1. Encode negation in the description text ("Use only when there is no Justfile, Makefile, or mise.toml") and rely on the model. Unreliable but cheap.
  2. Use a single skill with paths: ["pyproject.toml", "Justfile", "Makefile", "mise.toml"] and let the SKILL.md body branch on what it finds (via dynamic context injection !`ls`). This consolidates the decision into one skill body and is the most robust option today.
  3. Wrap activation in a hook (InstructionsLoaded / SessionStart) that injects different CLAUDE.md content based on flag files. Hooks have full shell access, so arbitrary boolean logic is trivial — but this is hook-land, not skill-land.

Question-by-question findings

1. Activation mechanism

Activation is primarily model-driven from description, and there is one declarative file-trigger field: paths.

From the official frontmatter reference table on the Skills docs page:

paths — Glob patterns that limit when this skill is activated. Accepts a comma-separated string or a YAML list. When set, Claude loads the skill automatically only when working with files matching the patterns. Uses the same format as path-specific rules.

So in the default case (no paths), the model decides based on the description that lives in the system prompt. With paths set, automatic loading is gated by glob match on the files Claude is working with.

allowed-tools is a permission/pre-approval field, not an activation field — it only affects what tools the skill may use once active. disable-model-invocation: true disables auto-activation entirely (only the user can /invoke it). user-invocable: false does the inverse (only the model can invoke it, hidden from / menu).

2. Glob negation

No documented negation syntax. The paths field uses the same glob format as .claude/rules/ path-specific rules, which the memory docs describe as:

Use glob patterns in the paths field to match files by extension, directory, or any combination... You can specify multiple patterns and use brace expansion to match multiple extensions in one pattern.

The documented patterns are all positive (**/*.ts, src/**/*, src/**/*.{ts,tsx}). Brace expansion works. No !pattern exclude syntax is documented anywhere in the Skills, Plugins-reference, or Memory pages.

Empirical evidence from the issue tracker corroborates this:

  • anthropics/claude-code#17204 lists every syntax that does and does not work for paths/globs. None of the tested forms involve negation. The author would surely have tried it if it were a feature.
  • Multiple open bugs (#21858, #23478, #23569, #16853) discuss the field still failing in mundane cases (user-level rules, Write tool, worktrees). The feature is not mature enough to expect undocumented negation to work even if hand-rolled.

Conclusion: glob negation in paths is not supported today. Expressing "X present AND Y absent" requires a workaround.

3. Manifest fields

SKILL.md frontmatter (official, from the Skills doc table):

Field Purpose
name Display name. Defaults to directory name. Lowercase, hyphens, max 64 chars.
description What the skill does and when to use it. Drives model-based activation. Up to 1024 chars.
when_to_use Extra trigger phrases. Appended to description, counts toward the 1,536-char listing cap.
argument-hint Autocomplete hint.
arguments Named positional args for $name substitution.
disable-model-invocation If true, only the user can invoke.
user-invocable If false, hide from / menu.
allowed-tools Tools pre-approved for this skill.
model Model override for this turn.
effort Effort-level override.
context Set to fork to run in a subagent.
agent Subagent type when context: fork.
hooks Skill-scoped lifecycle hooks.
paths Glob patterns gating auto-activation.
shell bash or powershell for !`...` injection.

plugin.json / marketplace.json: Per the Plugins reference, neither has activation-condition keys for skills. Skills are auto-discovered from the plugin's skills/ directory and gated only by whether the plugin is enabled. Activation logic lives in SKILL.md, not at the manifest level.

4. Priority / specificity

No priority field exists. When skills share a name across scopes there is a fixed override order (enterprise > personal > project; plugin skills are namespaced and don't conflict). Beyond name-conflict resolution there is no documented mechanism for declaring one sibling skill more specific than another. The model chooses among eligible skills based on description match. If paths filters narrow the eligible set, that narrowing is the only "specificity" lever available.

For listing-budget pressure, skillOverrides and skillListingBudgetFraction can drop or shorten descriptions of low-priority skills, but that's about token budget, not activation priority.

First-party skills using non-description signals

Searched anthropics/skills and anthropics/claude-plugins-official. The publicly indexed first-party skills (PDF, Excel, DOCX, PPTX, etc.) rely on description-based activation. I did not find a first-party SKILL.md using paths in the public repos within the time budget for this research. Plenty of community/third-party skills exist, but I cannot confirm any well-known one using paths from authoritative sources. Treat paths as a real but under-exercised feature — the open bug list (#17204, #21858, #23478, #23569, #16853) confirms it ships and is being used, but adoption is limited.

Citations