Claude Code Skills Design Patterns: Six Layers, One Decision Rule, Three Pitfalls

12 min readTech

Are you losing track of what goes where in Claude Code’s configuration?

CLAUDE.md, Rules, Commands, Skills, Agents, MCP, Plugins. Even after reading the official docs, “so where does this actually live?” stays murky. In my own setup, I started by cramming everything into CLAUDE.md — rules, workflows, decision criteria, all of it — and repeatedly hit the same problem: context overflow, where instructions from the first half of a long conversation would be forgotten by the time Claude reached the second.

Skills 2.0, introduced to Claude Code in May 2025, is a major expansion of the custom slash command system. It added context: fork to run a skill in an isolated context, allowed-tools to restrict which tools a skill can use, and a model field for per-skill model selection — widening the design space for structuring AI instructions considerably.

This article shares the layer-separation pattern I settled on, including Skills 2.0, and the pitfalls I hit along the way.

Mapping the Six Layers

Starting with the big picture. Claude Code’s configuration splits across six layers.

LayerRoleWhat goes there
RulesHow to behaveCoding conventions, naming rules, decision criteria
CommandsWhat to doWorkflows users invoke with /
SkillsHow to do itReusable domain-specific tasks
AgentsWho does itSubtasks delegated from skills
MCPWhat to connect toExternal system connections (Gmail, DB, etc.)
PluginsWhat’s availableOfficial tool extensions (browser automation, etc.)

The official docs cover each in detail:

Getting to this map took me a while. Early on, the boundary between Rules and Skills was fuzzy to me — “coding conventions” and “the PR review workflow” both ended up in the same CLAUDE.md.

The decision axis is simple: does it involve execution?

Principles and criteria with no execution → Rules (“how to behave”). Workflows that actually do something → Commands or Skills (“what to do”). That single axis goes a long way toward preventing CLAUDE.md from becoming a dumping ground.

How I Actually Use Them

Abstract frameworks only go so far, so here’s what my actual setup looks like.

Newsletter Auto-Triage

A /digest-newsletter command batch-processes unread newsletters in Gmail. It fetches unread mail via the Gmail integration, runs a quick triage pass on subject lines and opening text, and for flagged messages also fetches the full body and linked content. Everything gets sorted into must-read / story-candidate / skip, and a digest note lands in Obsidian automatically.

Twenty newsletters — link deep-dives included — processed into a single-run digest. I wrote up the full implementation in a separate article:

Daily Analytics

Every day, GA4 and Google Search Console data from the sites I run gets fetched, compared against the prior week, and saved to Obsidian. “Which pages grew vs. last week” comes to me rather than requiring me to navigate dashboards.

Zettelkasten Management

My Obsidian Vault’s knowledge management runs through a skill. It supports a three-stage conversion: FleetingNote (raw quick-captures) → LiteratureNote (structured summaries) → PermanentNote (my own synthesis). When I jot down notes while reading a technical article, the skill converts them into a structured summary and flags connections — “this relates to the note you wrote earlier about X.” It cuts the overhead of organizing and discovery while leaving the thinking itself to me.

Three Design Points Worth Getting Right

This is where it gets practical. Writing a skill is easy; writing a skill that works well takes some care.

1. Keep CLAUDE.md as an index

The classic mistake is putting coding conventions, workflows, and decision criteria all directly into CLAUDE.md.

CLAUDE.md is read at the start of every conversation. Make it large, and it consumes the AI’s context window before any real work begins — leading to instructions from the first half of long conversations being forgotten by the second half. I hit this problem repeatedly before I understood what was happening.

The fix is clear: don’t write concrete content in CLAUDE.md. Move rules to .claude/rules/, and leave only pointers (“see this file for details”) in CLAUDE.md. Loaded only when referenced, they don’t eat context by default. I’ve written about splitting rules across multiple projects here:

2. Use context: fork to isolate context

Skills 2.0’s context: fork runs a skill in a separate context from the main conversation. The skill’s content becomes the sub-agent’s prompt, consuming none of the main conversation’s context window. When it finishes, only the result returns.

This makes a real difference for skills that chew through large volumes of data. Processing 20 newsletters generates enormous context from email bodies and linked content. Without context: fork, by the time the skill is working through the later messages, the earlier instructions have quietly disappeared — this actually happened to me before I added the flag.

One caveat: context: fork only does useful work when the skill contains concrete task instructions. A skill that consists only of guidelines (“operate according to this approach”) gives the forked sub-agent nothing actionable. The fork flies blind.

3. Restrict tools with allowed-tools

Skills support an allowed-tools setting that limits which tools are available during execution.

Giving a research skill access to file editing and shell commands creates the risk of unintended side effects. Restricting to “read and search only” keeps it safely confined to its actual job.

---
name: seo-analyzer
description: Analyzes the site's SEO status
allowed-tools: ["Read", "Grep", "WebFetch"]
---

Grant only the minimum permissions the task requires. Same logic as any access control design.

Where to Start

If you’re currently putting everything into CLAUDE.md, the first move is this:

Extract one workflow from CLAUDE.md into a Skill.

A minimal SKILL.md looks like this:

---
name: my-first-skill
description: Describe concretely what this skill does
---

Write the workflow steps here

Drop this in .claude/skills/my-first-skill/SKILL.md and it’s immediately callable as /my-first-skill. Once that feels comfortable, add context: fork to experiment with context isolation, then narrow permissions with allowed-tools. Build incrementally — there’s no need to design the whole system upfront.

For combining this with the MCP layer — Gmail, database connections, and so on — I’ve written more detail here:

About this site

Personal blog by Amane Inoue. Writing about tech, books, culture, travel, and university life.