Skip to main content

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:

folder

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:

  1. Point out any violations of these standards
  2. Suggest specific improvements with examples
  3. Explain why the standard matters for maintainability
  4. Offer to rewrite code sections to meet standards
  5. Prioritize readability and maintainability over brevity