Lesson 1
Steering - The Foundation
The Core Idea
Every time you start a chat, Kiro assembles a context window. Into that window go: the system prompt, your message, any files you reference, and - crucially - your steering files. These are markdown files that live in .kiro/steering/ and shape how Kiro behaves across all sessions in that workspace.
You've already seen one in action - the session-context.md in this very workspace is a steering file.
Where Steering Lives
There are two scopes:
| Scope | Location | Applies to |
|---|---|---|
| Workspace | .kiro/steering/*.md | This workspace only |
| Global (User) | ~/.kiro/steering/*.md | Every workspace you open |
Only .md files directly in the steering/ folder are documented as being recognised - subdirectory support is not mentioned in official docs. To be safe, keep all steering files at the top level. Store supporting content (specs, schemas, reference docs) elsewhere in the workspace and reference them with #[[file:...]].
Global steering is for personal cross-project standards: "always use British English", "prefer functional patterns", "I use pnpm not npm". Workspace steering is for project-specific knowledge: "this is an Angular 18 app", "we use Tailwind", "API routes live in src/api/".
The Three Inclusion Modes
This is the key thing most people don't realise: not all steering files are loaded all the time. There are three modes, controlled by YAML front-matter at the top of the file. The front-matter schema is tiny - just two keys, and that's the complete set:
| Key | Values | Required |
|---|---|---|
inclusion | auto | fileMatch | manual | No (defaults to auto if omitted) |
fileMatchPattern | A glob string | Only when inclusion: fileMatch |
That's it. No other front-matter keys exist for steering files. Here's what each mode does:
1. Always-on (default)
---
inclusion: auto
---
# My Coding Standards
Always use TypeScript strict mode...
No front-matter, or inclusion: auto - loaded into every single session, every message. Use this sparingly. Every token here costs you context space in every interaction.
Note: in practice, a rule that's purely about TypeScript would be better as fileMatch against **/*.ts so it doesn't load when you're working on CSS, HTML, or JSON. Reserve always-on for truly cross-cutting rules (naming conventions, tooling preferences, project-wide architecture).
2. Conditional (fileMatch)
---
inclusion: fileMatch
fileMatchPattern: "src/app/services/**/*.ts"
---
# API Layer Conventions
All HTTP services must use HttpClient with typed responses and handle errors with catchError...
Only loaded when Kiro reads a file matching the glob pattern. This is powerful - you can have detailed API conventions that only activate when you're working on API files. Zero cost when you're in the UI layer.
#File in your message, or (3) the matching file is your active editor file. It does not trigger just because a matching file is open in a background tab - only when the file's content actually reaches Kiro.
3. Manual
---
inclusion: manual
---
# Database Migration Guide
When creating a new migration...
Never auto-loaded. You pull it in when you need it. Perfect for reference material that's too large to be always-on. There are two ways to invoke a manual steering file - both do the same thing (inject its content into context):
/- type slash in the chat input. Manual steering files appear in the slash-command menu alongside skills. This groups them with invokable things.#- type hash in the chat input. Manual steering files appear alongside files and folders. This groups them with contextual things.
Different entry point, identical result: the file's content is added to your conversation context for that message. The only practical distinction is what else shows up in each menu - / lists skills alongside manual steering (things you invoke), while # lists files, folders, and other context keys like #Problems, #Terminal, #Git Diff alongside manual steering (things that add context). Pick whichever menu matches your mental framing at the time.
The file appears in these menus using its filename (minus the .md extension). There's no name property in the front-matter to override this - so if your file is .kiro/steering/db-migrations.md, it shows up as "db-migrations". Name your files descriptively.
In short: always, when a matching file is read, or when you ask for it.
File References: Pulling in External Content
Steering files can reference other files in your workspace using a special syntax:
Follow the API patterns defined in #[[file:docs/api-spec.yaml]]
This is Kiro-specific syntax, not standard markdown. Kiro intercepts this directive and expands it - replacing it with the referenced file's actual content before anything reaches the model. Standard markdown has no concept of #[[file:...]]. So steering files are markdown plus this one special directive.
When Kiro loads that steering file, it also loads the referenced file's content. This is how you can point Kiro at an OpenAPI spec, a GraphQL schema, a style guide, or any other document without pasting its contents into the steering file itself.
The path is relative to the workspace root.
What Makes Good Steering
Steering files are injected raw into the context. Every word costs tokens. The best steering files are:
- Concise - state the rule, not the rationale (unless the rationale prevents misapplication)
- Actionable - "use
pnpm" not "we prefer pnpm because it's faster" - Scoped correctly - use fileMatch for domain-specific rules, not always-on
- Non-obvious - don't tell Kiro things it would infer from the code anyway (like "this is a TypeScript project" when
tsconfig.jsonexists)
A Practical Example
Here's how a real project might structure its steering:
.kiro/steering/
├── conventions.md # Always-on: code style, naming, tooling
├── architecture.md # Always-on: high-level structure, key patterns
├── api-standards.md # fileMatch: "src/app/services/**/*.ts" — HTTP/API conventions
├── component-patterns.md # fileMatch: "src/app/**/*.component.ts" — Angular component patterns
├── db-migrations.md # Manual — only when doing migrations
└── deployment.md # Manual — only when deploying
How Steering Relates to Everything Else
This is why we started here:
- Skills reference steering-format files and can include file references the same way
- Powers inject their steering files into the model's context when activated - the power's own
steering/directory contents are loaded on-demand, not physically added to your.kiro/steering/ - Hooks with
"type": "agent"actions inject prompt text, which is conceptually the same as steering but triggered by an event - Specs read steering to understand your project context before generating requirements
- Context management is the system that decides which steering files make it into the window - understanding inclusion modes is understanding context management
Quiz
You have a 200-line style guide that's only relevant when editing SCSS files. Which inclusion mode?
You want a rule that applies in this workspace AND every other workspace you open. Where does the file go?
Your steering file references #[[file:docs/openapi.yaml]]. When is that YAML loaded?
Your Tangible Win
You now understand the full mechanics of steering: three inclusion modes, two scopes, file references, and how it connects to every other Kiro feature. You can look at any .kiro/steering/ directory and immediately understand what's always-on, what's contextual, and what's on-demand.