Rules Concepts¶
Scopes¶
Scopes represent organizational contexts (company, team, project). Each scope is a directory containing:
metadata.yml- Scope configuration and parent referencescommandments.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 descriptionparents: 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:
- 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
- Parent categories in the hierarchy: If empty, traverse up the category path (e.g.,
python.web.testing→python.web→python) looking for a non-empty "when" - 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.