Writing your own style

A style is a folder holding a style.yml and a prompts/ directory. There is no code to write and nothing to register — drop the folder in and it appears in the + New Spec menu beside the built-ins.

  1. Where a style can live
  2. Changing one prompt without forking a style
  3. style.yml, key by key
  4. The four rules that decide everything
    1. 1. A stage is satisfied when its artifacts exist
    2. 2. kind: is either ai or implement
    3. 3. There is no requires: key
    4. 4. gate: manual parks the walk for a human
  5. Reference: style.yml
    1. Top level
    2. A spec type
    3. format
    4. A stage
    5. Load errors
  6. A prompt’s job
  7. Trying it

Where a style can live

Three places, and the folder name is the style’s id:

Scope Location
workspace <repo>/.local-workflows/styles/<id>/
profile ~/.local-workflows/styles/<id>/
builtin ships with the extension

Workspace wins over profile, which wins over builtin. Put a style in your profile to use it in every repository you open; put it in the workspace to commit it with the project, so the whole team runs the same process.

With a .code-workspace open, “workspace” means the workspace, not a repository. Styles are read from the workspace root’s .local-workflows/styles/, and a style committed inside one of the open repositories is not loaded. That is the same rule as spec placement: with several repositories open, the process is the workspace’s decision rather than each repository’s. See Workspaces.

Every style — built-in included — is parsed by the same code. That is what makes a shipped style and a hand-written one behave identically by construction, and what makes “eject a built-in and modify it” a file copy rather than a code generator.


Changing one prompt without forking a style

You usually do not need a whole style. The definition and the prompts resolve separately: the highest scope holding a style.yml supplies the definition, but every scope holding that id contributes prompts.

So to change how Kiro writes design documents, and nothing else:

.local-workflows/styles/kiro/prompts/design.md

No style.yml. Kiro’s own definition still drives the pipeline; your file replaces that one prompt. You inherit every later fix to the rest of the style instead of freezing a copy of it.


style.yml, key by key

schema: 1

# Names the process this implements. The folder name is the identity;
# this field asserts it.
id: my-process
name: My Process
desc: One line, shown in the style picker.

# NOT a stage. The first document is drafted in a native chat, because a
# conversation gets more out of a person than a form does. Declared here
# so the engine knows which stage a spec lands on when the file appears.
intake:
  prompt: prompts/intake.md
  produces: requirements.md

# What + New Spec offers. A single entry means nobody is asked.
specTypes:
  - id: feature
    label: Feature
    stages: [requirements, design, tasks, implement]
  - id: bug
    label: Bug fix
    stages: [requirements, tasks, implement]

# Read first by every phase: what this process is and that the document,
# not the reply, is the deliverable.
intro: prompts/intro.md

format:
  # Parser-critical rules. Given to every phase.
  grammar: prompts/grammar.md
  # House style, given only to the stage writing that document.
  house:
    requirements: prompts/format-requirements.md
    design: prompts/format-design.md
    tasks: prompts/format-tasks.md

stages:

  - id: requirements
    kind: ai
    produces: [requirements.md]
    gate: manual
    prompt: prompts/requirements.md

  - id: design
    kind: ai
    produces: [design.md]
    gate: manual
    prompt: prompts/design.md

  - id: tasks
    kind: ai
    produces: [tasks.md]
    mayProduce: [notes.md]      # written only when the work calls for it
    gate: manual
    prompt: prompts/tasks.md

  # The engine starts the session and does not wait. No artifacts, so
  # this stage is never satisfied - which makes it terminal.
  - id: implement
    kind: implement
    prompt: prompts/implement.md

The four rules that decide everything

Get these and the format stops needing memorisation.

1. A stage is satisfied when its artifacts exist

This one rule does the most work in the whole design. It is why a spec folder someone else wrote resumes at the right phase, why intake can write requirements.md before the pipeline starts, and why re-running a finished phase does nothing.

Its consequence: every stage must leave an artifact. A stage that writes nothing can never be satisfied, so the walk would park on it forever — which is why “review the documents and report” is not a phase.

2. kind: is either ai or implement

ai runs the prompt and waits for the artifacts it declared. An ai stage with no produces is refused at load — it could never complete.

implement starts the session and does not wait. Declare no produces and it can never be satisfied, which makes it terminal — how you say the work for this phase happens somewhere the engine cannot reach. That is what both shipped styles do. Give an implement stage a produces and it becomes satisfiable, and no longer terminal.

A terminal stage must be the last one a spec type visits. Anything listed after it is unreachable, because the walk stops at the first unsatisfied stage — so that is refused at load too, rather than shipping a phase nobody can reach.

3. There is no requires: key

What a stage needs is whatever the prior stages of that spec type produced. Declaring it per stage would state the pipeline twice, and the two copies would eventually disagree.

This is also why a stage can appear in several spec types with different args and no conditionals: in a Bug fix that skips design, the tasks stage simply sees one document instead of two.

4. gate: manual parks the walk for a human

Put the gate on the phase that depends on a document, not on the one that wrote it. What a person approves is “this is good enough to build on” — a judgement made when you are about to rely on it.


Reference: style.yml

Required keys: schema, id, name, desc, specTypes, format, stages. No unknown keys, and no requires: key exists — what a stage needs is rule 3 above. Every path is relative to the style folder.

Top level

Key Type Meaning
schema 1 Style schema version.
id string Must equal the folder name.
name string Shown in pickers.
desc string One line.
intro path Read first by every phase.
intake { prompt, produces } The native chat that seeds the first document. prompt is a path; produces is the expected file, relative to the spec folder. Not a stage.
specTypes list What + New Spec offers. One entry = no question asked.
format { grammar, house } The document contract.
stages list The pool of phases. Order here means nothing — a spec type’s list is the pipeline.

A spec type

Key Type Meaning
id string required
label string Shown in the picker.
stages string[] Ordered stage ids — this is the pipeline. A type that skips design just omits it here.

format

Key Type Meaning
grammar path required. The parser-critical contract (checkbox syntax, ## Open Questions). Handed to every phase.
house map Per-stage document style, keyed by stage id. A stage with no entry gets none.

A stage

Key Type Meaning
id string required. Also the session name, the format.house key, and the sdd.stages.<id> settings key.
kind ai | implement required. ai runs through the engine and waits for the document. implement starts a session and does not wait.
produces path | path[] All must exist for the stage to be satisfied. Required on ai.
mayProduce path | path[] Context when present; never gates satisfaction. Optional inputs need no declaration — only optional outputs do.
gate manual Park for a human before running. Omit to run when reached.
prompt path required. Overridable per file by a workspace style folder.

Load errors

Every one refused at load, never mid-run: id ≠ folder name · schema: missing, not a whole number, or newer than the build · stages: empty or a duplicated stage id · kind: ai with no produces · an artifact in both produces and mayProduce · kind: other than ai/implement · gate: other than manual · specTypes: empty or a duplicated id · a spec type listing no stages, naming an undefined stage, visiting a stage twice, or listing any stage after a terminal one.


A prompt’s job

Prompts are Markdown, and they are handed a specific, bounded context — never the whole folder, never a conversation.

Write a phase prompt about doing its job well. The pipeline, the deliverable-is-the-document rule, and the parser-critical grammar are already supplied by intro: and format.grammar:, to every phase. A prompt that re-explains them is duplicated text that will drift.

Keep an ## Open Questions section in your document format. It is the one hard block in the process: while it holds questions, the next phase will not start.


Trying it

  1. Run Local Workflows: Eject Style and pick a built-in. It copies the style’s files, byte for byte, into the scope you choose — your user profile (~/.local-workflows/styles/, the default, applies everywhere you work) or the workspace (committed with the repo). Existing files are listed and confirmed before anything is overwritten.
  2. To make it a new style rather than a replacement of the built-in, rename the folder and change id: and name: to match.
  3. Edit a prompt, or add a stage.
  4. Set { "sdd": { "style": "my-process" } } in .local-workflows/settings.json.
  5. + New Spec — your style is in the menu.

Starting from a copy rather than a blank file is the fastest path, because the shipped styles are heavily commented with the reasoning behind each key.

An ejected copy stops receiving improvements to the built-in. Kept under its original id it shadows the built-in outright. Reverting is deleting files — each file you remove falls back to the built-in.


Back to top

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


- 22-Aug-2026 08:02 PM +0000