Skip to content

Rules Concepts

Scopes

Scopes represent organizational contexts (company, team, project). Each scope is a directory containing:

  • metadata.yml - Scope configuration and parent references
  • commandments.yml - Mandatory rules (MUST)
  • suggestions.yml - Recommended rules (SHOULD)
.daimyo/rules/
├── python-general/
│   ├── metadata.yml
│   ├── commandments.yml
│   └── suggestions.yml
└── team-backend/
    ├── metadata.yml
    ├── commandments.yml
    └── suggestions.yml

Metadata Format

name: scope-name
description: Human-readable description
parents:
  - parent-scope-1
  - parent-scope-2
tags:
  team: backend
  language: python

Fields:

  • name: Scope identifier (must match directory name)
  • description: Human-readable description
  • parents: List of parent scopes (first = highest priority)
  • tags: Key-value pairs for organizing scope metadata (e.g., team, language, environment)
  • auth: Optional access-control block (see below)

Access Control (auth)

Restrict a scope to principals that hold specific JWT roles:

auth:
  accepted_roles:
    - "admin"
    - "daimyo-.*"   # regex patterns are supported
  roles_claim: roles  # optional; defaults to global oidc_roles_claim setting

accepted_roles is a list of Python regex patterns matched against the values of the JWT claim named by roles_claim. A request is authorised when at least one role value matches at least one pattern. Scopes without an auth block are publicly accessible.

See Authentication for details.

Categories

Categories are hierarchical subdivisions within rules:

python.web.testing:
  when: When testing web interfaces
  ruleset:
    - Use playwright for acceptance tests
    - Use pytest fixtures for test setup

Category Tags (Optional)

Categories can include tags for additional metadata:

development.coding.python:
  when: When writing Python code
  tags:
    - python
    - backend
    - performance-critical
  ruleset:
    - Use type hints for all function signatures
    - Follow PEP 8 naming conventions

Tags are displayed in markdown output: <tags>backend; performance-critical; python</tags>

Optional "when" Descriptions

The "when" field is optional. When omitted or empty, the system uses intelligent fallback:

python.testing:
  when: When writing tests for this project
  ruleset:
    - Use our custom test fixtures

python.web:
  ruleset:
    - Follow team web standards

Fallback priority:

  1. Category's merged "when" description: After scope merging (local extends remote, child extends parent scope), the category's "when" field is used if non-empty
  2. Parent categories in the hierarchy: If empty, traverse up the category path (e.g., python.web.testingpython.webpython) looking for a non-empty "when"
  3. Default: "These rules apply at all times"

The scope merging process (local → remote → parent) happens before the hierarchical fallback, ensuring child scopes can override descriptions from remote servers or parent scopes.

This allows:

  • Parent/remote scopes to define general descriptions
  • Child scopes to override only when needed
  • Hierarchical inheritance from broader to specific categories
  • Simplified child scopes that inherit descriptions

Rule Types

Commandments (MUST): Mandatory rules that accumulate through inheritance

Suggestions (SHOULD): Recommended rules that can be overridden or appended with + prefix

Why Not Nesting the Categories?

While it seems more intuitive, it proved to be confusing and harder to maintain in certain cases, e.g.:

  • Appending suggestions: it's confusing to know whether the + must be prepended to the innermost category, to the root category, or to a category in between.
  • Sharding categories: should it combine the innermost category or every category and subcategory defined?

For that reason it was decided to keep the categories at the root level, using the explicit path notation and nesting them logically using the dot path splitting.