# 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:

```text
.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**](06-lab-2-steer.md) · keep the [**Steering Reference Card**](11-steering-reference-card.md) open.
