Section 2 — Steering Claude Code

Summary — what this page covers The heart of Day 1, and the section that received the big update. It reframes the advanced features around a single decision — where does an instruction belong? — judged by when it loads, how it survives compaction, what it costs in context, and how much authority it carries. Then it teaches CLAUDE.md done right, the new Rules feature, skills as folders (corrected), subagents as markdown (corrected), hooks as the real guardrail, and packaging everything as a plugin. Pair with Lab 2 and the Steering Reference Card.

10:45 AM – 12:30 PM · 105 min — 50 min lecture/demo + 55 min lab

Learning objectives

  • Choose the right home for an instruction using four properties: when it loads, compaction behavior, context cost, authority

  • Split an overgrown CLAUDE.md into focused, path-scoped rules

  • Build a skill as a folder (SKILL.md + references/scripts); trigger by /name or auto-match

  • Configure a subagent (markdown + YAML frontmatter); run one async

  • Write hooks for deterministic automation — and know why a hook, not a CLAUDE.md line, is a guardrail

  • Package a team setup as a plugin

The steering model (lead with this)

Everything in this section answers one question: where does an instruction belong? You have many places to put guidance for Claude, and they differ on four properties — when it loads, how it survives compaction, what it costs in context, and how much authority it carries. Pick the home that matches the job.

Method When it loads Survives compaction Context cost Use it for
CLAUDE.md (root) Session start; re-read after compaction Yes (memoized) Always in context — keep < 200 lines Facts & soft conventions Claude needs all the time
CLAUDE.md (subdir) On-demand, when working in that folder Partial (reloads when relevant) Low — only when you're in that area Folder-specific facts
Rules Always (unscoped) or on file-match (path-scoped) Yes Low–medium Path-scoped coding conventions
Skills On /name, or auto-match by description n/a (invoked on demand) Low until triggered (only the description sits in context) A multi-step procedure (~30+ lines)
Subagents When spawned Isolated context; only the summary returns Cheap to the parent — runs in its own window Out-of-sight heavy work; a cost lever via model:
Hooks On events (deterministic) n/a (runs as code) None — executes outside the model "Every time X, do Y"; real guardrails (PreToolUse exit 2 blocks)
Output styles Session config n/a Minimal Changing how Claude formats responses
Append-system-prompt Session start (flag) Yes Adds to every turn One-off system-prompt additions

The three decisions you'll actually use:

  1. "Every time X, always do Y" → hook (the model choosing to run a formatter ≠ it running).

  2. "Never do X" → not a CLAUDE.md line. Real guardrails are deterministic: hooks (PreToolUse exit 2 blocks), permissions, and managed settings (org-wide, non-overridable).

  3. A 30-line procedure → skill. CLAUDE.md is for facts Claude needs all the time.

Content

Block 2A — Steering + CLAUDE.md done right (≈25 min)

Steering (Topic 8). Walk the table above column by column, then land the three decisions. The mental shortcut: the more deterministic and always-needed a piece of guidance is, the "lower" it should live (hook → rule → CLAUDE.md); the more procedural or occasional, the more it belongs in a skill or subagent. Demo: D-STEER.

CLAUDE.md as a map, not a junk drawer (Topic 9). A root CLAUDE.md is loaded at session start, memoized, and re-read after compaction — so it's in context on every turn. That power is also its cost: every line you add is paid for on every request. Treat it as a map that points Claude to where things are, not a junk drawer of everything you might ever want.

  • Root vs. subdirectory. Root = always-loaded project briefing. A CLAUDE.md in a subfolder loads on-demand when Claude works in that area — use it for folder-specific facts so the root stays lean.

  • Keep it under ~200 lines. If it's growing past that, the overflow usually wants to be a rule (a convention) or a skill (a procedure), not another CLAUDE.md paragraph.

  • Bootstrap and append. /init scaffolds one from your codebase; start a line with # mid-session to append a fact.

  • Don't put secrets or hard "never do X" prohibitions here — the first is a leak, the second isn't enforceable (see Block 2C).

Block 2B — Rules + Skills (≈40 min)

Custom commands — the light case (Topic 10). A command is just a saved prompt: drop a Markdown file in .claude/commands/, invoke it with /name, and pass input via the $ARGUMENTS placeholder. Great for a one-shot reusable prompt. The rule of thumb: when it needs steps or judgment, it's not a command — it's a skill.

Skills are folders (CORRECTION) (Topic 11). A skill is a folder, not a single file:

.claude/skills/<name>/
  SKILL.md          # the procedure + metadata
  references/       # supporting docs the skill can point Claude to
  scripts/          # helper scripts the skill can run
  • The skill's description is its trigger, written for the model — it's what lets Claude auto-match the skill to a request, so phrase it the way a user would ask. A vague description means the skill never fires.

  • The highest-value part is the Gotchas section — the non-obvious traps. Don't waste lines stating the obvious; spend them on what Claude would otherwise get wrong.

  • Skills are lazy: only the short description sits in context until the skill is triggered, so you can have many without bloating every turn. (There are nine skill categories; six matter for .NET work.) Demo: D4.

Rules — new this version (NEW) (Topic 12). Rules live in .claude/rules/*.md and carry an optional paths: glob in their frontmatter:

  • Unscoped (no paths:) = always loaded, like a focused slice of CLAUDE.md.
  • Path-scoped = loaded only when Claude reads a file matching the glob (e.g. a C# data-access rule that fires under BookTracker.Data/**/*.cs).

In Lab 2 you'll migrate the conventions from your Lab 1 CLAUDE.md into rules, trimming the root file back to a map. Two honest gotchas:

  • Rules load on read, not create. A path-scoped rule fires when an existing matching file is read — so a rule meant to guide creating new files may not trigger. Make creation-time rules unscoped.

  • User-level ~/.claude/rules/ paths: is currently unreliable — keep path-scoped rules at the project level. Demo: D4b.

Block 2C — Subagents + Hooks (≈30 min)

Subagents are markdown (CORRECTION) (Topic 13). A subagent is a .claude/agents/<name>.md file — Markdown with YAML frontmatter (name, description, optional model/tools); the body is its system prompt. Key behaviors:

  • It runs in isolated context — its own window — and only the final summary returns to your main thread. That keeps heavy, noisy work (large reads, exploratory analysis) from flooding your context.

  • model: claude-haiku-4-5 is a cost lever: send mechanical work to a cheaper model while your main session stays on Sonnet/Opus.

  • Skill vs. subagent: a skill runs in-thread and stays steerable as it goes; a subagent runs out-of-sight and hands back a summary. Reach for a subagent when you don't want the details in your main context. (Agent teams — several coordinated subagents — exist too; mentioned here in passing.)

Async subagents (Topic 14). Spawn a subagent, keep working in your main session, and get notified when it finishes — parallelism without context pollution. Demo: D5.

Hooks — the real guardrail (Topic 15). Hooks are deterministic automation that runs as code, on events, outside the model's choice:

  • Events: SessionStart, PreToolUse, PostToolUse, Stop, PreCompact.

  • Five types: command, HTTP, mcp_tool, prompt, agent.

  • Register them in settings.json, in managed settings (org-wide), or in a skill's frontmatter.

  • A PreToolUse hook that exits with code 2 blocks the action. This is why "never do X" is a hook, not a CLAUDE.md line: a CLAUDE.md prohibition is a suggestion the model may follow; a PreToolUse exit-2 hook is enforcement that cannot be skipped. Demo: D6 — the guardrail.

Plugins (Topic 16). A plugin bundles skills + subagents + hooks + output styles into one installable unit. Check .claude/ into the repo so the whole team inherits the same setup, or publish to a marketplace for wider sharing. Demo: D6b (the lab lead-in).

What changed from the previous version of this section (call out for returning attendees): skills are folders (not single files), subagents are .md (not .yaml), Rules is new, and hard prohibitions belong in hooks/permissions, not CLAUDE.md.

Demos referenced here

D-STEER · D4 (skill folder) · D4b (rules) · D5 (subagent + async) · D6 (guardrail hook) · D6b (plugin). [Scripts in _instructor/demo-plan.md.]

→ Continue to Lab 2 · keep the Steering Reference Card open.