How to Use System Rules for Path-Based Review Customization in Open Code Review

System rules in Open Code Review provide default review behavior that you can override or merge with user-defined rules using glob patterns in a YAML configuration file.

Open Code Review (OCR) from Alibaba implements a layered rule system that lets you customize code review behavior for specific file paths. The system rules serve as a built-in fallback layer handling binary detection, language-specific linting, and generic review policies. By adding user rules in .ocr_rules.yaml, you can target specific paths with tailored review instructions while optionally preserving or replacing the system defaults.

Understanding the Rule Resolution Architecture

OCR's rule engine operates through a clear precedence model. The system resolves which rule applies to each file through a multi-stage pipeline before generating LLM prompts.

System Rule Layer

The foundation resides in internal/config/rules/system_rules.go. This file defines the SystemRule struct containing glob patterns mapped to rule text, plus a DefaultRule for unmatched files. The LoadDefault() function parses embedded rule definitions into a runtime resolver.

// From internal/config/rules/system_rules.go
type SystemRule struct {
    Patterns    []PatternRule
    DefaultRule string
}

User Rule Loader

Your customizations enter through internal/config/rules/loader.go. This module reads .ocr_rules.yaml and constructs a Resolver implementing the same interface as the system resolver. User rules take precedence—OCR checks them first in declaration order.

Resolution in the Scan Agent

During actual scanning at internal/scan/agent.go, the resolution call looks like this:

ruleText := a.args.SystemRule.Resolve(strings.ToLower(it.Path))

The lowercase normalization ensures case-insensitive path matching across platforms.

Creating Path-Based Rule Customizations

Define your rules in .ocr_rules.yaml at your project root. Each entry contains a glob pattern, the rule text, and an optional merge_system_rule flag.

Basic Override Pattern


# .ocr_rules.yaml

rules:
  - pattern: "**/*.go"
    rule: |
      # Go-specific review rule

      - Check for gofmt / go vet issues
      - Enforce proper error handling
      - Verify context propagation in function signatures

  - pattern: "docs/**"
    rule: |
      # Documentation rule

      - Verify Markdown headings hierarchy (single H1)
      - Ensure code snippets are syntactically correct
      - Flag broken internal links
    merge_system_rule: true

In this example:

  • Go files receive only the Go-specific rule (default replace behavior)
  • Documentation files receive both system rules and custom rules (merged)

Pattern Precedence

Rules evaluate in list order. Place more specific patterns before general ones:

rules:
  - pattern: "internal/crypto/**/*.go"  # Specific first

    rule: "Apply cryptography security audit..."
  
  - pattern: "**/*.go"                # General fallback

    rule: "Apply standard Go review..."

Merging vs. Replacing System Rules

The merge_system_rule boolean controls combination behavior. When true, OCR concatenates the system rule with your custom rule, separated by a delimiter. This preserves binary detection and safety checks while adding domain-specific guidance.

Setting Behavior Use Case
false (default) Replace system rule entirely Fully custom review for mature codebases
true Append to system rule Augment rather than supplant defaults

The merge logic appears in internal/delegate/rulegroup.go, which also clusters files sharing identical resolved rule text for efficient batch processing.

CLI Commands for Rule Management

Review with Custom Rules

ocr review --config .ocr_rules.yaml ./src/main.go

Preview Effective Rules

ocr rules --path src/main.go

This invokes cmd/opencodereview/rules_cmd.go to display the resolved rule without executing a full review.

Programmatic Rule Resolution

For tooling integrations, use the Go API directly:

package main

import (
    "strings"
    
    "github.com/alibaba/open-code-review/internal/config/rules"
    "github.com/alibaba/open-code-review/internal/scan"
)

func resolveRulesForPath(filePath string) (string, error) {
    // Load user rules
    userResolver, err := rules.LoadFile(".ocr_rules.yaml")
    if err != nil {
        return "", err
    }
    
    // Load system rules as fallback
    sysResolver, err := rules.LoadDefault()
    if err != nil {
        return "", err
    }
    
    normalized := strings.ToLower(filePath)
    ruleText := userResolver.Resolve(normalized)
    
    // Check if merge is requested for this path
    if detail, ok := userResolver.(rules.DetailResolver); ok {
        sysText := sysResolver.Resolve(normalized)
        ruleText = mergeRules(sysText, ruleText)
    }
    
    return ruleText, nil
}

The DetailResolver interface exposure in internal/config/rules/loader.go enables introspection of per-rule merge preferences.

Rule Grouping for Efficient Reviews

internal/delegate/rulegroup.go implements an optimization: files with identical resolved rule text get grouped together. This allows the LLM reviewer to process batches sharing the same instructions, reducing token overhead and maintaining context consistency.

The grouping key is the complete resolved rule text, so two files with different merge configurations (one merged, one replaced) will not group together even if their final rule text happens to match.

Summary

Frequently Asked Questions

What happens if no user rule matches a file path?

The system falls back to SystemRule.Resolve() which returns either a pattern-matched system rule or the DefaultRule. This ensures every file receives review instructions even without user configuration.

Can I disable system rules entirely for specific paths?

Yes. Omit merge_system_rule or set it to false. The resolved rule will contain only your custom text. However, this removes safety checks like binary file detection—use with caution for security-sensitive repositories.

Does pattern order matter in .ocr_rules.yaml?

Absolutely. The resolver evaluates patterns sequentially and stops at the first match. Place specific patterns (e.g., internal/api/**/*.go) before general ones (e.g., **/*.go) to ensure correct precedence.

How do I verify which rule applies without running a full review?

Use ocr rules --path <filepath>. This command instantiates the same resolver chain used during review but outputs the resolved text instead of invoking the LLM, as implemented in cmd/opencodereview/rules_cmd.go.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →