Skip to content

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 applies
  • katas: 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 nodes
  • type (required): one of the ten types above
  • description: human-readable label (used on all types except decision)
  • next: ID of the successor node; required on all types except terminator and fork
  • condition: the decision question (decision nodes only)
  • alternatives: list of {case, next} pairs (decision nodes only)
  • branches: list of branch-start node IDs (fork nodes only, replaces next)
  • role (optional): responsible role or persona
  • inputs / 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:

KataSet → KataCategory → Kata
RuleSet → Category     → Rule

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)
  • when override: if the child provides a when value, 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.