> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Path-Specific Rules

> Conditional rules by path that apply automatically based on the files being discussed

**Path-Specific Rules** is a ChatCLI conditional rules system that automatically applies instructions based on the file paths being discussed or edited in the conversation. Instead of loading all rules all the time, the system detects which files are in context and injects only the relevant rules.

<Info>
  Path Rules complement the [bootstrap](/features/bootstrap-memory) system (RULES.md). While RULES.md defines global rules, Path Rules defines rules specific to parts of the codebase.
</Info>

***

## Concept

The idea is simple: different parts of the codebase have different conventions. Go code follows different rules than HTML templates. Tests have different patterns than production code. Path Rules lets you define all of this granularly.

```text theme={"system"}
Conversation mentions auth/handler.go
      |
      v
Path matcher: "auth/**" -> auth-rules.md
Path matcher: "*.go"    -> go-rules.md
      |
      v
Rules injected into system prompt
(only the relevant ones)
```

***

## File Structure

Rules are placed in the `.chatcli/rules/` directory (workspace) or `~/.chatcli/rules/` (global):

```text theme={"system"}
.chatcli/rules/
|-- go-rules.md          # Rules for Go files
|-- test-rules.md        # Rules for test files
|-- api-rules.md         # Rules for the API module
|-- migration-rules.md   # Rules for database migrations
+-- security-rules.md    # Rules for security modules
```

### File Format

Each rule file is Markdown with YAML frontmatter containing the `paths` field:

```yaml theme={"system"}
---
paths:
  - "*.go"
  - "**/*.go"
description: "Rules for Go code"
---
# Go Rules

## Style
- Use `gofmt` as the default formatter
- Variable names in camelCase
- Interfaces with "-er" suffix when they have a single method (Reader, Writer)

## Errors
- Always check returned errors
- Use `fmt.Errorf("context: %w", err)` for wrapping
- Never use `panic()` in production code

## Tests
- Use table-driven tests
- Name subtests descriptively
- Use `t.Helper()` in test helper functions
```

***

## Precedence

<Tabs>
  <Tab title="Workspace vs Global">
    Rules exist at two levels with workspace taking priority:

    | Level         | Directory               | Priority                |
    | :------------ | :---------------------- | :---------------------- |
    | **Workspace** | `.chatcli/rules/*.md`   | High (overrides global) |
    | **Global**    | `~/.chatcli/rules/*.md` | Low (fallback)          |

    If a rule file with the same name exists at both levels, the workspace version takes precedence.
  </Tab>

  <Tab title="Multiple rules">
    When a file matches multiple patterns, **all** matching rules are injected:

    ```text theme={"system"}
    File: auth/handler_test.go

    Rules applied:
      1. go-rules.md        (match: *.go)
      2. test-rules.md      (match: *_test.go)
      3. api-rules.md       (match: auth/**)
    ```

    Rules are concatenated in the order rule files are found (alphabetical).
  </Tab>
</Tabs>

***

## Glob Matching

The `paths` field uses glob patterns to match file paths:

| Pattern            | Matches                                         |
| :----------------- | :---------------------------------------------- |
| `*.go`             | Go files in the root directory                  |
| `**/*.go`          | Go files in any subdirectory                    |
| `*_test.go`        | Go test files                                   |
| `src/**`           | All files inside `src/`                         |
| `auth/**`          | All files inside `auth/`                        |
| `*.{ts,tsx}`       | TypeScript and TSX files                        |
| `migrations/*.sql` | SQL files in `migrations/`                      |
| `Dockerfile*`      | Dockerfiles (Dockerfile, Dockerfile.prod, etc.) |

<Tip>
  Use `**` for recursive matching in subdirectories. The pattern `*.go` matches only in the root directory, while `**/*.go` matches across the entire tree.
</Tip>

***

## Lazy Loading

Path Rules uses **lazy loading** based on conversation hints:

<Steps>
  <Step title="Context detection">
    ChatCLI analyzes recent messages and tool calls to identify which files are in context (read, edited, mentioned).
  </Step>

  <Step title="Pattern matching">
    Detected paths are compared against the `paths` patterns of each rule file.
  </Step>

  <Step title="Selective injection">
    Only rules that match files in context are injected into the system prompt.
  </Step>

  <Step title="Dynamic update">
    Every turn, patterns are re-evaluated. New rules can be injected and irrelevant rules can be removed.
  </Step>
</Steps>

<Info>
  Lazy loading ensures the system prompt doesn't get overloaded with irrelevant rules. Only rules needed for the files under discussion are loaded, saving tokens.
</Info>

***

## Rule Examples

<Tabs>
  <Tab title="Go">
    `.chatcli/rules/go-rules.md`:

    ```yaml theme={"system"}
    ---
    paths:
      - "**/*.go"
    description: "Project Go conventions"
    ---
    # Go Rules

    - Use `errors.New()` or `fmt.Errorf()` for errors, never raw strings
    - Exported functions MUST have a godoc comment
    - Use `context.Context` as the first parameter when applicable
    - Prefer `sync.Mutex` over channels for simple shared state
    - Do not use `init()` except for driver registration
    ```
  </Tab>

  <Tab title="Tests">
    `.chatcli/rules/test-rules.md`:

    ```yaml theme={"system"}
    ---
    paths:
      - "**/*_test.go"
      - "**/*.test.ts"
      - "**/*.spec.ts"
    description: "Patterns for test files"
    ---
    # Test Rules

    - Use table-driven tests in Go
    - Name subtests with clear English descriptions
    - Avoid excessive mocking -- prefer fakes or simple stubs
    - Each test should be independent and idempotent
    - Use `t.Parallel()` when the test doesn't depend on global state
    ```
  </Tab>

  <Tab title="Security">
    `.chatcli/rules/security-rules.md`:

    ```yaml theme={"system"}
    ---
    paths:
      - "auth/**"
      - "security/**"
      - "**/middleware/auth*"
    description: "Security rules for critical modules"
    ---
    # Security Rules

    - NEVER log tokens, passwords, or API keys
    - Use `crypto/rand` for token generation, NEVER `math/rand`
    - Validate ALL user inputs before processing
    - Use prepared statements for SQL queries (injection prevention)
    - Implement rate limiting on authentication endpoints
    - JWT tokens must have a maximum expiration of 1 hour
    ```
  </Tab>

  <Tab title="Migrations">
    `.chatcli/rules/migration-rules.md`:

    ```yaml theme={"system"}
    ---
    paths:
      - "migrations/**"
      - "db/migrations/**"
    description: "Rules for database migrations"
    ---
    # Migration Rules

    - Always include UP and DOWN operations
    - Names in format: YYYYMMDDHHMMSS_description.sql
    - Avoid ALTER TABLE on large tables without a downtime plan
    - Use explicit transactions (BEGIN/COMMIT)
    - Do not use DROP COLUMN in production without prior deprecation
    - Add indexes on fields used in WHERE and JOIN clauses
    ```
  </Tab>
</Tabs>

***

## Viewing Active Rules

You can check which rules are currently active:

```text theme={"system"}
User: Which path rules are active?

Agent: Based on the files in context, the following rules are active:

  Active Path Rules:
    go-rules.md       (match: auth/handler.go, auth/jwt.go)
    security-rules.md (match: auth/handler.go, auth/jwt.go)
    test-rules.md     (match: auth/handler_test.go)

  Total: 3 rules, ~450 tokens
```

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Specific rules" icon="crosshairs">
    Define precise path patterns. Rules that are too broad (`**/*`) waste tokens on irrelevant contexts.
  </Card>

  <Card title="Concise rules" icon="compress">
    Keep each rule file short and focused. Long rules consume more tokens.
  </Card>

  <Card title="Version in Git" icon="code-branch">
    Put `.chatcli/rules/` in your repository to share with the team.
  </Card>

  <Card title="Combine with RULES.md" icon="layer-group">
    Use RULES.md for global rules and Path Rules for rules specific to areas of the codebase.
  </Card>
</CardGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Bootstrap and Memory" icon="memory" href="/features/bootstrap-memory">
    Configure RULES.md for global rules that complement Path Rules.
  </Card>

  <Card title="Customizable Agents" icon="user-gear" href="/features/customizable-agents">
    Combine Path Rules with specialized agents for maximum context.
  </Card>
</CardGroup>
