Dev.to · 9 min read

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

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 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 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 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 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 Claude Code documentation: Skill content lifecycle, visibility, and listing budget Agent Skills specification: Progressive disclosure Previous article: From Invocation to Safe Execution Related future reading: the Claude Code Context Management series on compaction, and the Claude Code Memory series on what returns after compaction.

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More AI & Machine Learning News