DEV Community

Zhengxin
Zhengxin

Posted on

Claude Code Skills Deep Dive (8): From Loading to Compaction

TL;DR: A Skill has four easily confused states: its source on disk, candidate metadata, the rendered content produced by a particular invocation, and the copy preserved after compaction. Editing SKILL.md changes future discovery and invocation, not instructions already in the conversation. An inline Skill's body persists across turns, while its temporary tool approval does not. Compaction preserves recent invoked content within per-Skill and combined budgets; it does not reread the entire source.

Part 7: From Invocation to Safe Execution exposed one lifecycle split: Skill instructions may remain in context after the allowed-tools grant expires on the next user message.

That is not the only split. The common intuition that “the Skill is the SKILL.md file on disk” stops being useful once a session starts. At runtime, at least four objects matter.

Four states, four update events

A · Source file
    SKILL.md and supporting files on disk
        ↓ discovery
B · Candidate metadata
    name and description known in this session
        ↓ invocation and rendering
C · Rendered invocation
    body with arguments, variables, and dynamic context expanded
        ↓ conversation growth and compaction
D · Post-compaction preserved copy
    recent Skill content reattached within a budget
Enter fullscreen mode Exit fullscreen mode
State Created when Updated by
Source Skill is created or installed Edits, plugin updates, version changes
Candidate listing Session discovers it Live detection, scope or visibility changes
Rendered invocation User or Claude invokes it New arguments, dynamic output, reinvocation
Post-compaction copy Conversation compacts Retention budget and recency of invocations

Without these names, phrases such as “the Skill was updated,” “the Skill is loaded,” and “the Skill is still active” are ambiguous.

Session startup: first comes a candidate index

In an ordinary Claude Code session, Skills available for model invocation contribute names and descriptions to the candidate listing. Claude knows what it might choose, but the full SKILL.md body has not entered the conversation. References, scripts, and assets do not load automatically either.

This is progressive disclosure's first level—and its fixed discovery cost. A user-only Skill need not advertise a full description for model matching. Visibility settings can also reduce an entry to name-only or hide it.

“Installed” means the source exists. “Listed as a candidate” means the current model has a chance to select it.

First invocation: rendered content enters the conversation

On activation, Claude Code reads the source, substitutes arguments, runs permitted dynamic context commands, and creates rendered content. The Claude Code documentation describes the result as a single message added to the conversation. It can influence later turns, not just the answer immediately following invocation:

Turn 1: /release-check
        → full instructions enter the messages

Turn 2: user adds “staging only”
        → earlier Skill instructions remain in history

Turn 3: Claude continues checking
        → the workflow need not be reread from disk
Enter fullscreen mode Exit fullscreen mode

That enables multi-turn workflows. It also means each token in the main body is more than a one-time activation cost: later requests continue to carry it until the conversation is compacted or reset.

Instructions persist; temporary permissions do not

This is easy to misread:

Turn 1: /commit is invoked
        allowed-tools temporarily pre-approves Git commands

Turn 2: instructions still exist in context
        allowed-tools grant has cleared
Enter fullscreen mode Exit fullscreen mode

Claude still knows the commit process, but a sensitive tool call may require approval again. The product has not “forgotten” the Skill. Knowledge and authorization intentionally have different lifetimes. If approval should last the session, use a session permission rule. If it should be granted again for just one turn, reinvoke the Skill.

Editing the source does not rewind conversation history

Claude Code detects edits to Skill definitions in watched locations. A changed SKILL.md can update the candidate description and future invocations. It does not search the message history for an earlier rendered copy and replace it:

T0: invoke Skill v1 → rendered v1 enters context
T1: edit disk source to v2 → source and candidate metadata update
T2: continue chatting → rendered v1 remains in the messages
Enter fullscreen mode Exit fullscreen mode

History records what was actually loaded at the time. Silently rewriting it would break conversational continuity.

To use v2, invoke the Skill again, start a fresh session, or explicitly tell Claude that the new version supersedes earlier instructions. Live reload updates a definition; it is not a time machine.

Reinvocation compares rendered content

The same Skill can be called twice in one session. If the second rendered result is identical to a copy already in context, Claude Code adds a brief “already loaded” note instead of duplicating the full body. If the rendered result differs, it appends the new content.

Differences can come from changed arguments, dynamic shell output, an edited source file, or runtime variables. /fix-issue 123 and /fix-issue 456 are distinct rendered task inputs even though both use the same Skill name.

The practical deduplication key is the rendered content, not merely the Skill's name.

Dynamic context makes repeated calls naturally different

Suppose a Skill includes !git status --short``. The first invocation sees a clean workspace; the second sees five modified files. The source did not change, but the rendered body did.

Reinvocation can refresh a snapshot, and frequent reinvocation can also append repeated large outputs to context. Keep injected output compact and limited to state that actually affects the workflow.

Supporting resources have no special residency promise

If SKILL.md tells Claude to read a reference, that read becomes an ordinary tool result in the conversation. It follows normal message and compaction behavior simply because it was read; being inside a Skill directory does not grant it permanent residency.

Likewise, unread script source is not in context; a script's output enters as a tool result if executed; an asset enters history if read. Files remain on disk for later access. The folder is persistent source, while the conversation holds only the path through it actually taken this time.

Forked Skills live primarily in a child context

An inline Skill's rendered body enters the main conversation. With context: fork, the body is instead a subagent task in a separate context. The child carries the rendered Skill and its intermediate reads and tool results; the main conversation receives the returned findings rather than the entire child work history.

This is why forked Skills fit long, self-contained investigations, but not a reference that the main agent must keep following line by line. For that, use inline loading or return the necessary rules explicitly.

Compaction: a generic summary may lose the method

As a conversation grows, Claude Code compacts earlier history into a summary. If all the summary retained were “the user invoked release-check,” the name would survive but its steps, constraints, and resource navigation might not. Claude would struggle to continue the workflow.

Claude Code therefore reattaches content from invoked Skills after compaction. It does not reread every source file. It preserves recorded rendered invocations, subject to a budget:

`text
compact summary

  • recovered project context
  • preserved invoked-Skill content → post-compaction context `

That is stronger recovery than an arbitrary early chat message gets, but it is not unlimited.

Two retention budgets: 5K per Skill, 25K overall

The current documentation specifies:

  • At most the first 5,000 tokens of each invoked Skill are reattached.
  • Reattached Skills share a 25,000-token combined budget.
  • The most recently invoked Skill gets space first.
  • Older Skills may be dropped entirely when many have been invoked.

`text
Most recent
Skill E 5K
Skill D 5K
Skill C 5K
Skill B 5K
Skill A 5K
── 25K total
Older Skills may not be reattached
`

Three implications follow. A SKILL.md longer than 5K tokens may lose its tail after compaction. Many active Skills can crowd older ones out. Critical constraints placed at the end are more likely to disappear than those near the top. This is a design reason to keep the main body concise and put essential rules first.

Compaction preserves the invoked snapshot, not the latest source

Consider:

`text
T0: invoke v1
T1: edit source to v2
T2: compact the conversation
`

Compaction should preserve the rendered v1 that the conversation actually used, rather than silently rewriting past constraints with v2. Source defines future invocations; the invocation record tells us what was loaded then; preservation carries that record forward.

If the user wants v2 after compaction, invoke v2. Do not treat an edit on disk as a hot replacement for active instructions.

The candidate listing has a budget too

Compaction limits invoked bodies. Startup discovery has another budget: the Skill listing. Claude Code scales its character budget to 1% of the model context window. When the list overflows, names remain, but descriptions for less-used Skills can be dropped. /context and /doctor help inspect this cost.

Installing 500 Skills does not yield 500 equally well-described automatic matches. Disk capacity is not the bottleneck; metadata visibility is.

The skillOverrides setting offers four useful states:

Setting Listed to Claude User / menu
on Name and description Shown
name-only Name only Shown
user-invocable-only Hidden Shown
off Hidden Hidden

This lets users reduce noise from a shared project Skill without modifying the repository's SKILL.md.

A new conversation keeps the source, not the invocation

The Skill folder persists on disk; the rendered invocation belongs to a conversation. After /clear or a fresh session, the source still exists and can be discovered again, but yesterday's loaded instructions do not automatically remain active. The Skill must be invoked when relevant to the new task.

This differs from memory. Memory preserves background across sessions; a Skill stores a reusable method. Its source survives, but “we were at step four of this release yesterday” should not become part of the Skill definition. Resume the session or keep a task handoff record instead.

The lifecycle in one picture

`text
Install or create on disk
SKILL.md + resources
↓
Session discovery
name + description listing
↓ match
Invocation
arguments + variables + dynamic context
↓
Rendered content
one inline instruction message, or a forked subagent task
↓
Later turns
instructions persist; temporary permission grant expires
↓
Compaction
up to 5K each, 25K total, recent first
↓
New session
source rediscovered; invocation must happen again
`

A Skill is not a file continuously mirrored into context. Source determines how future calls render; rendered content records what this call actually loaded; compaction carries that snapshot forward only within its budget.

Up next

Once a Skill matures in a personal folder, it may move into a project and later a plugin or marketplace. Copying files distributes content but does not solve namespaces, versions, dependencies, or cross-surface differences. Part 9 follows a capability from a local experiment to an installable component.

References

Top comments (0)