Custom rules
Customize Otto's behavior with rules tailored to your team's workflow and preferences.
Organization​
All custom rules must be located in the rules
subfolder within a dedicated otto
directory in your Ascend Project:
- Screenshot
- File tree

├── otto
│  ├── agents
│  │  ├── custom_agent.md
│  ├── mcp.yaml
│  ├── otto.yaml
│  └── rules
│  └── demo_welcome.yaml
│  └── git_commits.yaml
Rule structure​
Otto rules are markdown files with YAML frontmatter that define when and how the rule should be applied. Each rule file contains:
Frontmatter configuration​
- alwaysApply: Boolean indicating whether Otto should always apply this rule regardless of context
- description: String containing a clear explanation of what the rule does and when it applies
- globs: Array of file patterns specifying which files or directories the rule affects (e.g.,
*.py
,src/**/*.sql
,flows/
) - keywords: Array of terms or concepts that trigger this rule from chat (e.g.,
database
,transformation
,error-handling
)
Rule body​
The markdown body contains the actual instructions that Otto will follow when the rule is triggered.
Example​
This example shows how to enforce team coding standards, ensuring consistency and maintainability:
coding_standards.md
---
otto:
rule:
alwaysApply: false
description: >
Enforce coding standards and best practices for Python files
in Ascend Projects. Applies when reviewing code, creating new files, or
discussing code quality.
globs:
- "*.py"
- "*.sql"
- "*.yaml"
- "*.yml"
- "flows/**/*"
- "transforms/**/*"
- "components/**/*"
keywords:
- code review
- standards
- best practices
- refactor
- clean code
- style guide
- formatting
- documentation
---
## Coding Standards
When working with code in this project, Otto must enforce the following standards:
### Python Standards
- Use **snake_case** for variable and function names
- Use **PascalCase** for class names
- Include **docstrings** for all functions and classes using Google style
- Limit line length to **88 characters** (Black formatter standard)
- Use **type hints** for function parameters and return values
- Follow **PEP 8** guidelines for imports (stdlib, third-party, local)
- Use **f-strings** for string formatting instead of `.format()` or `%`
- Include **error handling** with specific exception types
Example:
```python
def process_data_frame(df: pd.DataFrame, column_name: str) -> pd.DataFrame:
"""Process a DataFrame by cleaning the specified column.
Args:
df: Input DataFrame to process
column_name: Name of the column to clean
Returns:
Processed DataFrame with cleaned column
Raises:
ValueError: If column_name is not found in DataFrame
"""
if column_name not in df.columns:
raise ValueError(f"Column '{column_name}' not found in DataFrame")
return df.dropna(subset=[column_name])
General Standards​
- Always validate inputs and handle edge cases
- Use meaningful variable and function names
- Remove commented-out code before committing
- Include TODO comments for future improvements
- Test code changes before suggesting them
- Explain complex logic in comments
- Follow DRY (Don't Repeat Yourself) principles
- Use consistent formatting throughout the project
When Otto reviews or creates code, it must:
- Point out any violations of these standards
- Suggest specific improvements with examples
- Explain why the standard matters for maintainability
- Offer to rewrite code sections to meet standards
- Prioritize readability and maintainability over brevity