Jinja2 Templates¶
Rules, category descriptions, prologues, epilogues, and the default category description support Jinja2 templates for dynamic content based on configuration and scope metadata.
Available Template Variables¶
Templates can access:
- Configuration: All
DAIMYO_*environment variables and settings fromconfig/settings.toml - Scope metadata:
scope.name,scope.description,scope.tags,scope.sources - Category info:
category.key,category.when(in rule text only) - Daimyo version:
daimyo_version— the running version of daimyo (e.g.,1.15.0)
Basic Example¶
Configuration (config/settings.toml):
Rules with templates (commandments.yml):
python.monitoring:
when: "When monitoring {{ scope.name }} in {{ scope.tags.env | default('dev') }}"
ruleset:
- "Alert {{ TEAM_NAME }} via {{ SLACK_CHANNEL }}"
- "Log level: {{ LOG_LEVEL }}"
Rendered output (assuming scope.tags.env = "production"):
## python.monitoring
*When monitoring my-service in production*
- **MUST**: Alert Backend Team via #backend
- **MUST**: Log level: INFO
Best Practices¶
Always use the default filter for optional variables:
Conditionals:
Multiple variables:
Error Handling¶
Daimyo handles template errors gracefully. When templates fail to render (missing context variables, unavailable filters/tests), the system:
- Removes the failed element from the main response body
- Collects failure information
- Reports failures in a separate section (minimal format for LLMs)
JSON/YAML responses include a template_failures field:
{
"metadata": { ... },
"commandments": { ... },
"suggestions": { ... },
"template_failures": [
{
"element_type": "rule",
"element_identifier": "python.web rule #2",
"template_text": "Use {{ UNDEFINED_VAR }} ...",
"error_message": "'UNDEFINED_VAR' is undefined",
"variable_name": "UNDEFINED_VAR"
}
]
}
Markdown responses include a compact failures section wrapped in <ignore-failed-template> tags:
<ignore-failed-template>
## Template Failures
**python.web rule #2**: `UNDEFINED_VAR` undefined
```
Use {{ UNDEFINED_VAR }} for configuration
```
**python.testing rule #5**: `TEST_FRAMEWORK` undefined
```
Use {{ TEST_FRAMEWORK }} for all tests
```
</ignore-failed-template>
Failed elements are removed from the main response body and only appear in this diagnostic section. The <ignore-failed-template> tags provide a clear signal to LLMs to completely ignore this information. The format is concise while still showing the original template content for debugging.
Use Cases¶
Environment-aware rules:
python.deployment:
when: "When deploying to {{ scope.tags.region }}"
ruleset:
- "Deploy to {{ scope.tags.region }} region"
- "{% if scope.tags.env == 'production' %}Require manual approval{% endif %}"
- "Notification: {{ SLACK_DEPLOY_CHANNEL | default('#deployments') }}"
Team-specific rules:
code-review:
when: "When reviewing code for {{ TEAM_NAME }}"
ruleset:
- "Review in {{ CODE_REVIEW_TOOL | default('SonarQube') }}"
- "Require approval from {{ scope.tags.team }} lead"
Version-aware rules:
general:
ruleset:
- "These rules require daimyo {{ daimyo_version }} or later"
- "{% if daimyo_version >= '1.15' %}Use the MCP server interface{% endif %}"
Templated prologues and epilogues:
rules_markdown_prologue = '''
# Rules for {{ scope.name }}
*{{ scope.description }}*
These rules are {{ "critical" if scope.tags.env == "production" else "recommended" }}.
'''
rules_markdown_epilogue = "Questions? Contact {{ TEAM_NAME | default('the team') }} via {{ SLACK_CHANNEL | default('#general') }}"
default_category_description = "Rules for {{ category.key }} - applies in {{ scope.name }}"