Katas Concepts¶
Katas are the procedural complement to rules. Where a rule says what must or should be done ("Use type hints for all function signatures"), a kata says how to do something ("When adding type hints to a module — step 1: run mypy to find untyped signatures, step 2: …"). Katas are named, reusable, and retrieved on demand by agents when they need step-by-step guidance for a recurring task.
| Aspect | Rule | Kata |
|---|---|---|
| Purpose | Prescriptive constraint (MUST/SHOULD) | Step-by-step procedure |
| Storage | commandments.yml / suggestions.yml |
katas.yml |
| Fields | text, rule_type |
name, procedure |
| Merging | Commandments additive; suggestions override | Override by name |
Kata YAML Format¶
katas.yml uses the same category key structure as rule files, but replaces ruleset with a katas dictionary mapping kata names to their procedures:
python:
testing:
when: "When starting a TDD cycle for a Python function"
katas:
tdd-cycle: |
1. Write a failing test for the target behaviour. Run `pytest -x` — confirm it fails.
2. Write the minimal implementation to make it pass. Run `pytest -x` — confirm it passes.
3. Refactor for clarity without changing behaviour. Run `pytest` — confirm all tests pass.
bdd-scenario: |
1. Define the scenario in plain language: Given / When / Then.
2. Write the step definitions as pytest fixtures or functions.
3. Run the scenario and confirm it passes.
Fields:
when(optional): present-tense trigger condition describing when the kata applieskatas: dictionary mapping kata names (kebab-case) to procedure strings; procedures support Jinja2 templates
Flowchart Kata Format (fcyaml)¶
When a procedure body begins with the literal line #!fcyaml, it is treated as a flowchart definition rather than plain text. Jinja2 templating is applied first; the result is then parsed as YAML and linearized into numbered markdown steps via depth-first traversal.
Supported node types:
type |
Display label | Purpose |
|---|---|---|
terminator |
[Start/End] |
Entry and exit points |
process |
[Process] |
A regular sequential step |
decision |
[Decision] |
Branch with condition + alternatives list |
input |
[Input] |
Data input consumed by the procedure |
output |
[Output] |
Data output produced by the procedure |
predefined_process |
[Sub-process] |
Reference to another kata or sub-flowchart |
manual_operation |
[Manual Operation] |
A step performed manually by a person |
manual_input |
[Manual Input] |
Human-entered data |
fork |
[Fork] |
Parallel split: branches lists first node IDs of each concurrent path |
sync |
[Sync] |
Parallel join: waits for all branches before continuing |
Node fields:
id(required): unique identifier referenced by other nodestype(required): one of the ten types abovedescription: human-readable label (used on all types exceptdecision)next: ID of the successor node; required on all types exceptterminatorandforkcondition: the decision question (decisionnodes only)alternatives: list of{case, next}pairs (decisionnodes only)branches: list of branch-start node IDs (forknodes only, replacesnext)role(optional): responsible role or personainputs/outputs(optional): list of data source/destination names
Back-edges (a next pointing to an earlier step) are annotated as "Return to step N (retry)" rather than "Go to step N", making retry loops explicit.
The first node in the list is the entry point. Plain procedures (without #!fcyaml) are unaffected by this feature.
Domain Model¶
Katas mirror the rule domain model:
A KataSet holds categories keyed by their dot-path. A KataCategory holds a when description and a dictionary of named Kata objects, each with a name and a procedure string.
Merging Strategy¶
When scope inheritance resolves a merged scope:
- Same name, same category: child kata replaces parent kata entirely (no step merging)
whenoverride: if the child provides awhenvalue, it replaces the parent's for that category- New categories: child categories not present in the parent are added additively
Scope Directory¶
katas.yml is optional. A scope directory without it simply has no katas:
.daimyo/rules/
├── python-general/
│ ├── metadata.yml
│ ├── commandments.yml
│ ├── suggestions.yml
│ └── katas.yml ← optional
└── team-backend/
├── metadata.yml
├── commandments.yml
├── suggestions.yml
└── katas.yml ← optional
Category Filtering¶
Kata endpoints accept the same ?categories= prefix filter as rule endpoints. categories=python.testing matches python.testing, python.testing.unit, and any other descendant. See REST API and MCP Server for usage.
Category Disambiguation¶
When two categories in the same scope define a kata with identical names, use the optional category parameter to target a specific one. Without it, the first matching kata encountered during scope resolution is returned:
- MCP:
get_kata("setup", "my-scope", "python.testing") - REST:
GET /api/v1/scopes/my-scope/katas/setup?category=python.testing
Master Server Federation¶
When a master_server_url is configured, katas defined on the remote server are fetched alongside rules and merged into the local scope. Remote katas are treated as the base; local katas override them by name within the same category. This means a team server can publish shared kata libraries that project-level scopes can override or extend.