Steering files

A steering file is a Markdown file with your project’s rules for the AI: coding style, how the API is laid out, what to never touch. The header at the top of the file says when a chat gets it. The format is Kiro’s, so steering files you already wrote for Kiro work here without changes.

Off by default. Turn it on in settings.json, in your profile or in the workspace’s .local-workflows/settings.json for the whole team:

{
  "features": {
    "steering": true
  }
}

While it is off, no steering file is looked for, no chat gets the steering tool, and #name in a compose box is plain text.

  1. Where they can live
  2. The header
  3. fileMatch
  4. #name
  5. Tags
  6. Which providers
  7. How this differs from Kiro

Where they can live

Anywhere in the folders the chat works in: the working folder, and the workspace folders open in the window. .kiro/steering/ works, and so does src/api/rules.md.

Not read:

  1. Anything git ignores, and anything in .git or node_modules.
  2. Your home folder’s ~/.kiro/steering/.

The header

The header is the block between two --- lines at the very top of the file. A file is a steering file only if its header has inclusion:. A README.md, a docs page, or a file with no header at all is never used. So is a file with tags: and no inclusion:: blog posts and docs pages carry tags: too, and they are not rules for the AI.

---
inclusion: always
---

# How we write C#

- One class per file.
- ...
Header What happens
inclusion: always Attached to the first message of every chat.
inclusion: fileMatch Attached to an SDD implement wave whose Files: lines match its pattern. See fileMatch.
inclusion: manual + tags: [api, dotnet] Not attached. The AI loads it by tag when its work needs it. See Tags.
inclusion: manual Attached to one message when you type #name in a compose box. See #name.
inclusion: auto Not used. Add tags: to it instead.
No header, or no inclusion: Not used.

“Every chat” means SDD phases, each SDD implement wave, ai@1 steps in a workflow, and every compose box - the AI chat sidebar and its editor tab included. Follow-up messages and continued chats do not get the files again: the chat already has them.

A file with a header this build cannot read, such as inclusion: sometimes, or fileMatch with no pattern, is skipped, and the run log says which file and why.

fileMatch

---
inclusion: fileMatch
fileMatchPattern: "src/api/**"
---

# How our API controllers look
...

fileMatchPattern is one pattern or a list: ["*.ts", "*.tsx"].

  1. Where it works: SDD implement only. When a wave starts, its tasks’ Files: lines are checked against every pattern, and each file that matches is attached to that wave’s chat.
  2. Where it does not: everywhere else. Other SDD phases, workflow steps and the compose box do not know which files the chat will touch before it starts, and a file the AI happens to open later never pulls one in. That is on purpose: it is how Kiro ends up filling chats with rules nobody needed.
  3. For the rest, add tags: too. A fileMatch file with tags is attached when a wave’s files match, and offered through the steering tool everywhere else.

Patterns are relative to the repository:

Pattern Matches
src/api/** everything under src/api/, at any depth
src/**/*.ts every .ts file under src/
src/*.ts .ts files directly in src/, not deeper
*.tsx every .tsx file, at any depth. A pattern with no / matches the file name alone.
src/{api,web}/*.ts .ts files directly in src/api/ or src/web/
src/?.ts src/a.ts, src/b.ts: ? is one character

Case does not matter. [abc] character sets are not supported.

#name

Type # and a manual steering file’s name in any compose box, and that file is attached to that one message. The name is the file name without .md, case ignored: #api-rules finds api-rules.md in any folder.

  1. Works in every compose box: an SDD phase, an implement wave’s chat, a workflow run’s AI Session tab, and the AI chat sidebar or its editor tab.
  2. Only manual files. An always file is already in the chat.
  3. The message is sent exactly as you typed it, #api-rules included.
  4. Two files with the same name are both attached.
  5. A #word that names no manual file is left alone, and the log says No manual steering file named #word. #12 and issue#12 are not read as names.

Tags

An always file is read in every chat, even when the work has nothing to do with it. Tags are for everything else.

---
inclusion: manual
tags: [api, errors]
---

# How our REST errors look
...

Each chat gets a steering tool. Its description lists every tag in the project and the files under each one. The AI calls it with the tags that fit its work, and gets those files’ text back. Until it asks, a tagged file costs one line in the tool’s description.

  1. Tags are your own words. Pick words that say what the rules are about, like api, payments, database. The AI sees the file names next to each tag, but a vague tag like misc is still hard for it to choose.
  2. Case does not matter: API and api are the same tag.
  3. A file with inclusion: always and tags is attached, and the tool does not offer it again.
  4. A project with no tagged files gets no steering tool at all.
  5. Every call goes in the run log: the tags the AI asked for, and the files it got. If a tag is never asked for, rename it or make the file always.

Write tagged files as inclusion: manual plus tags:. With manual, Kiro itself loads the file only when someone types #name, and this extension offers it through the tool.

A file with tags: and no inclusion: is not a steering file here at all, so the header needs both.

Which providers

Provider always and fileMatch files steering tool
ghcp Yes Yes
claude Yes Yes
ACP providers (kiro-cli, gemini-cli, …) Yes No

ACP agents get attachments but cannot be given the engine’s own tools, so tagged files do not reach them.

How this differs from Kiro

  1. No header means not used. Kiro attaches a file with no header to every chat.
  2. Any folder, not only .kiro/steering/. A steering file outside .kiro/steering/ works here, and Kiro itself ignores it.
  3. tags: is this extension’s own key, not Kiro’s.
  4. fileMatch works in SDD implement only, against the wave’s Files: lines. Kiro matches files as the chat opens them.
  5. manual works through #name only. Kiro also offers it as a slash command.
  6. auto is not used. Add tags: instead.

Back to top

Local Workflows is a VS Code extension. Everything it does is declared in a YAML file you own.


- 11-Oct-2026 07:45 PM +0000